Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitcad86e2

Browse files
committed
WAL must log CREATE and DROP DATABASE operations *without* using any
explicit paths, so that the log can be replayed in a data directorywith a different absolute path than the original had. To avoid forcinginitdb in the 8.0 branch, continue to accept the old WAL log recordtypes; they will never again be generated however, and the code can bedropped after the next forced initdb. Per report from Oleg Bartunov.We still need to think about what it really means to WAL-log CREATETABLESPACE commands: we more or less have to put the absolute pathinto those, but how to replay in a different context??
1 parentbd9b4a9 commitcad86e2

File tree

2 files changed

+142
-31
lines changed

2 files changed

+142
-31
lines changed

‎src/backend/commands/dbcommands.c

Lines changed: 112 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
*
1616
*
1717
* IDENTIFICATION
18-
* $PostgreSQL: pgsql/src/backend/commands/dbcommands.c,v 1.154 2005/03/12 21:33:55 tgl Exp $
18+
* $PostgreSQL: pgsql/src/backend/commands/dbcommands.c,v 1.155 2005/03/23 00:03:28 tgl Exp $
1919
*
2020
*-------------------------------------------------------------------------
2121
*/
@@ -438,23 +438,17 @@ createdb(const CreatedbStmt *stmt)
438438
/* Record the filesystem change in XLOG */
439439
{
440440
xl_dbase_create_recxlrec;
441-
XLogRecDatardata[3];
441+
XLogRecDatardata[1];
442442

443443
xlrec.db_id=dboid;
444+
xlrec.tablespace_id=dsttablespace;
445+
xlrec.src_db_id=src_dboid;
446+
xlrec.src_tablespace_id=srctablespace;
447+
444448
rdata[0].buffer=InvalidBuffer;
445449
rdata[0].data= (char*)&xlrec;
446-
rdata[0].len= offsetof(xl_dbase_create_rec,src_path);
447-
rdata[0].next=&(rdata[1]);
448-
449-
rdata[1].buffer=InvalidBuffer;
450-
rdata[1].data= (char*)srcpath;
451-
rdata[1].len=strlen(srcpath)+1;
452-
rdata[1].next=&(rdata[2]);
453-
454-
rdata[2].buffer=InvalidBuffer;
455-
rdata[2].data= (char*)dstpath;
456-
rdata[2].len=strlen(dstpath)+1;
457-
rdata[2].next=NULL;
450+
rdata[0].len=sizeof(xl_dbase_create_rec);
451+
rdata[0].next=NULL;
458452

459453
(void)XLogInsert(RM_DBASE_ID,XLOG_DBASE_CREATE,rdata);
460454
}
@@ -1076,18 +1070,15 @@ remove_dbtablespaces(Oid db_id)
10761070
/* Record the filesystem change in XLOG */
10771071
{
10781072
xl_dbase_drop_recxlrec;
1079-
XLogRecDatardata[2];
1073+
XLogRecDatardata[1];
10801074

10811075
xlrec.db_id=db_id;
1076+
xlrec.tablespace_id=dsttablespace;
1077+
10821078
rdata[0].buffer=InvalidBuffer;
10831079
rdata[0].data= (char*)&xlrec;
1084-
rdata[0].len= offsetof(xl_dbase_drop_rec,dir_path);
1085-
rdata[0].next=&(rdata[1]);
1086-
1087-
rdata[1].buffer=InvalidBuffer;
1088-
rdata[1].data= (char*)dstpath;
1089-
rdata[1].len=strlen(dstpath)+1;
1090-
rdata[1].next=NULL;
1080+
rdata[0].len=sizeof(xl_dbase_drop_rec);
1081+
rdata[0].next=NULL;
10911082

10921083
(void)XLogInsert(RM_DBASE_ID,XLOG_DBASE_DROP,rdata);
10931084
}
@@ -1190,6 +1181,86 @@ dbase_redo(XLogRecPtr lsn, XLogRecord *record)
11901181
if (info==XLOG_DBASE_CREATE)
11911182
{
11921183
xl_dbase_create_rec*xlrec= (xl_dbase_create_rec*)XLogRecGetData(record);
1184+
char*src_path;
1185+
char*dst_path;
1186+
structstatst;
1187+
1188+
#ifndefWIN32
1189+
charbuf[2*MAXPGPATH+100];
1190+
#endif
1191+
1192+
src_path=GetDatabasePath(xlrec->src_db_id,xlrec->src_tablespace_id);
1193+
dst_path=GetDatabasePath(xlrec->db_id,xlrec->tablespace_id);
1194+
1195+
/*
1196+
* Our theory for replaying a CREATE is to forcibly drop the
1197+
* target subdirectory if present, then re-copy the source data.
1198+
* This may be more work than needed, but it is simple to
1199+
* implement.
1200+
*/
1201+
if (stat(dst_path,&st)==0&&S_ISDIR(st.st_mode))
1202+
{
1203+
if (!rmtree(dst_path, true))
1204+
ereport(WARNING,
1205+
(errmsg("could not remove database directory \"%s\"",
1206+
dst_path)));
1207+
}
1208+
1209+
/*
1210+
* Force dirty buffers out to disk, to ensure source database is
1211+
* up-to-date for the copy. (We really only need to flush buffers for
1212+
* the source database, but bufmgr.c provides no API for that.)
1213+
*/
1214+
BufferSync();
1215+
1216+
#ifndefWIN32
1217+
1218+
/*
1219+
* Copy this subdirectory to the new location
1220+
*
1221+
* XXX use of cp really makes this code pretty grotty, particularly
1222+
* with respect to lack of ability to report errors well. Someday
1223+
* rewrite to do it for ourselves.
1224+
*/
1225+
1226+
/* We might need to use cp -R one day for portability */
1227+
snprintf(buf,sizeof(buf),"cp -r '%s' '%s'",
1228+
src_path,dst_path);
1229+
if (system(buf)!=0)
1230+
ereport(ERROR,
1231+
(errmsg("could not initialize database directory"),
1232+
errdetail("Failing system command was: %s",buf),
1233+
errhint("Look in the postmaster's stderr log for more information.")));
1234+
#else/* WIN32 */
1235+
if (copydir(src_path,dst_path)!=0)
1236+
{
1237+
/* copydir should already have given details of its troubles */
1238+
ereport(ERROR,
1239+
(errmsg("could not initialize database directory")));
1240+
}
1241+
#endif/* WIN32 */
1242+
}
1243+
elseif (info==XLOG_DBASE_DROP)
1244+
{
1245+
xl_dbase_drop_rec*xlrec= (xl_dbase_drop_rec*)XLogRecGetData(record);
1246+
char*dst_path;
1247+
1248+
dst_path=GetDatabasePath(xlrec->db_id,xlrec->tablespace_id);
1249+
1250+
/*
1251+
* Drop pages for this database that are in the shared buffer
1252+
* cache
1253+
*/
1254+
DropBuffers(xlrec->db_id);
1255+
1256+
if (!rmtree(dst_path, true))
1257+
ereport(WARNING,
1258+
(errmsg("could not remove database directory \"%s\"",
1259+
dst_path)));
1260+
}
1261+
elseif (info==XLOG_DBASE_CREATE_OLD)
1262+
{
1263+
xl_dbase_create_rec_old*xlrec= (xl_dbase_create_rec_old*)XLogRecGetData(record);
11931264
char*dst_path=xlrec->src_path+strlen(xlrec->src_path)+1;
11941265
structstatst;
11951266

@@ -1245,9 +1316,9 @@ dbase_redo(XLogRecPtr lsn, XLogRecord *record)
12451316
}
12461317
#endif/* WIN32 */
12471318
}
1248-
elseif (info==XLOG_DBASE_DROP)
1319+
elseif (info==XLOG_DBASE_DROP_OLD)
12491320
{
1250-
xl_dbase_drop_rec*xlrec= (xl_dbase_drop_rec*)XLogRecGetData(record);
1321+
xl_dbase_drop_rec_old*xlrec= (xl_dbase_drop_rec_old*)XLogRecGetData(record);
12511322

12521323
/*
12531324
* Drop pages for this database that are in the shared buffer
@@ -1278,14 +1349,29 @@ dbase_desc(char *buf, uint8 xl_info, char *rec)
12781349
if (info==XLOG_DBASE_CREATE)
12791350
{
12801351
xl_dbase_create_rec*xlrec= (xl_dbase_create_rec*)rec;
1352+
1353+
sprintf(buf+strlen(buf),"create db: copy dir %u/%u to %u/%u",
1354+
xlrec->src_db_id,xlrec->src_tablespace_id,
1355+
xlrec->db_id,xlrec->tablespace_id);
1356+
}
1357+
elseif (info==XLOG_DBASE_DROP)
1358+
{
1359+
xl_dbase_drop_rec*xlrec= (xl_dbase_drop_rec*)rec;
1360+
1361+
sprintf(buf+strlen(buf),"drop db: dir %u/%u",
1362+
xlrec->db_id,xlrec->tablespace_id);
1363+
}
1364+
elseif (info==XLOG_DBASE_CREATE_OLD)
1365+
{
1366+
xl_dbase_create_rec_old*xlrec= (xl_dbase_create_rec_old*)rec;
12811367
char*dst_path=xlrec->src_path+strlen(xlrec->src_path)+1;
12821368

12831369
sprintf(buf+strlen(buf),"create db: %u copy \"%s\" to \"%s\"",
12841370
xlrec->db_id,xlrec->src_path,dst_path);
12851371
}
1286-
elseif (info==XLOG_DBASE_DROP)
1372+
elseif (info==XLOG_DBASE_DROP_OLD)
12871373
{
1288-
xl_dbase_drop_rec*xlrec= (xl_dbase_drop_rec*)rec;
1374+
xl_dbase_drop_rec_old*xlrec= (xl_dbase_drop_rec_old*)rec;
12891375

12901376
sprintf(buf+strlen(buf),"drop db: %u directory: \"%s\"",
12911377
xlrec->db_id,xlrec->dir_path);

‎src/include/commands/dbcommands.h

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/commands/dbcommands.h,v 1.36 2004/12/31 22:03:28 pgsql Exp $
10+
* $PostgreSQL: pgsql/src/include/commands/dbcommands.h,v 1.37 2005/03/23 00:03:37 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -18,22 +18,47 @@
1818
#include"nodes/parsenodes.h"
1919

2020
/* XLOG stuff */
21-
#defineXLOG_DBASE_CREATE0x00
22-
#defineXLOG_DBASE_DROP0x10
21+
#defineXLOG_DBASE_CREATE_OLD0x00
22+
#defineXLOG_DBASE_DROP_OLD0x10
23+
#defineXLOG_DBASE_CREATE0x20
24+
#defineXLOG_DBASE_DROP0x30
2325

24-
typedefstructxl_dbase_create_rec
26+
/*
27+
* Note: "old" versions are deprecated and need not be supported beyond 8.0.
28+
* Not only are they relatively bulky, but they do the Wrong Thing when a
29+
* WAL log is replayed in a data area that's at a different absolute path
30+
* than the original.
31+
*/
32+
33+
typedefstructxl_dbase_create_rec_old
2534
{
2635
/* Records copying of a single subdirectory incl. contents */
2736
Oiddb_id;
2837
charsrc_path[1];/* VARIABLE LENGTH STRING */
2938
/* dst_path follows src_path */
39+
}xl_dbase_create_rec_old;
40+
41+
typedefstructxl_dbase_drop_rec_old
42+
{
43+
/* Records dropping of a single subdirectory incl. contents */
44+
Oiddb_id;
45+
chardir_path[1];/* VARIABLE LENGTH STRING */
46+
}xl_dbase_drop_rec_old;
47+
48+
typedefstructxl_dbase_create_rec
49+
{
50+
/* Records copying of a single subdirectory incl. contents */
51+
Oiddb_id;
52+
Oidtablespace_id;
53+
Oidsrc_db_id;
54+
Oidsrc_tablespace_id;
3055
}xl_dbase_create_rec;
3156

3257
typedefstructxl_dbase_drop_rec
3358
{
3459
/* Records dropping of a single subdirectory incl. contents */
3560
Oiddb_id;
36-
chardir_path[1];/* VARIABLE LENGTH STRING */
61+
Oidtablespace_id;
3762
}xl_dbase_drop_rec;
3863

3964
externvoidcreatedb(constCreatedbStmt*stmt);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp