|
9 | 9 | *
|
10 | 10 | *
|
11 | 11 | * IDENTIFICATION
|
12 |
| - * $PostgreSQL: pgsql/src/backend/commands/dbcommands.c,v 1.141 2004/08/2905:06:41 momjian Exp $ |
| 12 | + * $PostgreSQL: pgsql/src/backend/commands/dbcommands.c,v 1.142 2004/08/2921:08:47 tgl Exp $ |
13 | 13 | *
|
14 | 14 | *-------------------------------------------------------------------------
|
15 | 15 | */
|
@@ -385,6 +385,30 @@ createdb(const CreatedbStmt *stmt)
|
385 | 385 | (errmsg("could not initialize database directory")));
|
386 | 386 | }
|
387 | 387 | #endif/* WIN32 */
|
| 388 | + |
| 389 | +/* Record the filesystem change in XLOG */ |
| 390 | +{ |
| 391 | +xl_dbase_create_recxlrec; |
| 392 | +XLogRecDatardata[3]; |
| 393 | + |
| 394 | +xlrec.db_id=dboid; |
| 395 | +rdata[0].buffer=InvalidBuffer; |
| 396 | +rdata[0].data= (char*)&xlrec; |
| 397 | +rdata[0].len= offsetof(xl_dbase_create_rec,src_path); |
| 398 | +rdata[0].next=&(rdata[1]); |
| 399 | + |
| 400 | +rdata[1].buffer=InvalidBuffer; |
| 401 | +rdata[1].data= (char*)srcpath; |
| 402 | +rdata[1].len=strlen(srcpath)+1; |
| 403 | +rdata[1].next=&(rdata[2]); |
| 404 | + |
| 405 | +rdata[2].buffer=InvalidBuffer; |
| 406 | +rdata[2].data= (char*)dstpath; |
| 407 | +rdata[2].len=strlen(dstpath)+1; |
| 408 | +rdata[2].next=NULL; |
| 409 | + |
| 410 | +(void)XLogInsert(RM_DBASE_ID,XLOG_DBASE_CREATE,rdata); |
| 411 | +} |
388 | 412 | }
|
389 | 413 | heap_endscan(scan);
|
390 | 414 | heap_close(rel,AccessShareLock);
|
@@ -970,11 +994,27 @@ remove_dbtablespaces(Oid db_id)
|
970 | 994 | }
|
971 | 995 |
|
972 | 996 | if (!rmtree(dstpath, true))
|
973 |
| -{ |
974 | 997 | ereport(WARNING,
|
975 | 998 | (errmsg("could not remove database directory \"%s\"",
|
976 |
| -dstpath), |
977 |
| -errhint("Look in the postmaster's stderr log for more information."))); |
| 999 | +dstpath))); |
| 1000 | + |
| 1001 | +/* Record the filesystem change in XLOG */ |
| 1002 | +{ |
| 1003 | +xl_dbase_drop_recxlrec; |
| 1004 | +XLogRecDatardata[2]; |
| 1005 | + |
| 1006 | +xlrec.db_id=db_id; |
| 1007 | +rdata[0].buffer=InvalidBuffer; |
| 1008 | +rdata[0].data= (char*)&xlrec; |
| 1009 | +rdata[0].len= offsetof(xl_dbase_drop_rec,dir_path); |
| 1010 | +rdata[0].next=&(rdata[1]); |
| 1011 | + |
| 1012 | +rdata[1].buffer=InvalidBuffer; |
| 1013 | +rdata[1].data= (char*)dstpath; |
| 1014 | +rdata[1].len=strlen(dstpath)+1; |
| 1015 | +rdata[1].next=NULL; |
| 1016 | + |
| 1017 | +(void)XLogInsert(RM_DBASE_ID,XLOG_DBASE_DROP,rdata); |
978 | 1018 | }
|
979 | 1019 |
|
980 | 1020 | pfree(dstpath);
|
@@ -1063,3 +1103,105 @@ get_database_name(Oid dbid)
|
1063 | 1103 |
|
1064 | 1104 | returnresult;
|
1065 | 1105 | }
|
| 1106 | + |
| 1107 | +/* |
| 1108 | + * DATABASE resource manager's routines |
| 1109 | + */ |
| 1110 | +void |
| 1111 | +dbase_redo(XLogRecPtrlsn,XLogRecord*record) |
| 1112 | +{ |
| 1113 | +uint8info=record->xl_info& ~XLR_INFO_MASK; |
| 1114 | + |
| 1115 | +if (info==XLOG_DBASE_CREATE) |
| 1116 | +{ |
| 1117 | +xl_dbase_create_rec*xlrec= (xl_dbase_create_rec*)XLogRecGetData(record); |
| 1118 | +char*dst_path=xlrec->src_path+strlen(xlrec->src_path)+1; |
| 1119 | +structstatst; |
| 1120 | +#ifndefWIN32 |
| 1121 | +charbuf[2*MAXPGPATH+100]; |
| 1122 | +#endif |
| 1123 | + |
| 1124 | +/* |
| 1125 | + * Our theory for replaying a CREATE is to forcibly drop the target |
| 1126 | + * subdirectory if present, then re-copy the source data. This |
| 1127 | + * may be more work than needed, but it is simple to implement. |
| 1128 | + */ |
| 1129 | +if (stat(dst_path,&st)==0&&S_ISDIR(st.st_mode)) |
| 1130 | +{ |
| 1131 | +if (!rmtree(dst_path, true)) |
| 1132 | +ereport(WARNING, |
| 1133 | +(errmsg("could not remove database directory \"%s\"", |
| 1134 | +dst_path))); |
| 1135 | +} |
| 1136 | + |
| 1137 | +#ifndefWIN32 |
| 1138 | +/* |
| 1139 | + * Copy this subdirectory to the new location |
| 1140 | + * |
| 1141 | + * XXX use of cp really makes this code pretty grotty, particularly |
| 1142 | + * with respect to lack of ability to report errors well. Someday |
| 1143 | + * rewrite to do it for ourselves. |
| 1144 | + */ |
| 1145 | + |
| 1146 | +/* We might need to use cp -R one day for portability */ |
| 1147 | +snprintf(buf,sizeof(buf),"cp -r '%s' '%s'", |
| 1148 | +xlrec->src_path,dst_path); |
| 1149 | +if (system(buf)!=0) |
| 1150 | +ereport(ERROR, |
| 1151 | +(errmsg("could not initialize database directory"), |
| 1152 | +errdetail("Failing system command was: %s",buf), |
| 1153 | +errhint("Look in the postmaster's stderr log for more information."))); |
| 1154 | +#else/* WIN32 */ |
| 1155 | +if (copydir(xlrec->src_path,dst_path)!=0) |
| 1156 | +{ |
| 1157 | +/* copydir should already have given details of its troubles */ |
| 1158 | +ereport(ERROR, |
| 1159 | +(errmsg("could not initialize database directory"))); |
| 1160 | +} |
| 1161 | +#endif/* WIN32 */ |
| 1162 | +} |
| 1163 | +elseif (info==XLOG_DBASE_DROP) |
| 1164 | +{ |
| 1165 | +xl_dbase_drop_rec*xlrec= (xl_dbase_drop_rec*)XLogRecGetData(record); |
| 1166 | + |
| 1167 | +/* Drop pages for this database that are in the shared buffer cache */ |
| 1168 | +DropBuffers(xlrec->db_id); |
| 1169 | + |
| 1170 | +if (!rmtree(xlrec->dir_path, true)) |
| 1171 | +ereport(WARNING, |
| 1172 | +(errmsg("could not remove database directory \"%s\"", |
| 1173 | +xlrec->dir_path))); |
| 1174 | +} |
| 1175 | +else |
| 1176 | +elog(PANIC,"dbase_redo: unknown op code %u",info); |
| 1177 | +} |
| 1178 | + |
| 1179 | +void |
| 1180 | +dbase_undo(XLogRecPtrlsn,XLogRecord*record) |
| 1181 | +{ |
| 1182 | +elog(PANIC,"dbase_undo: unimplemented"); |
| 1183 | +} |
| 1184 | + |
| 1185 | +void |
| 1186 | +dbase_desc(char*buf,uint8xl_info,char*rec) |
| 1187 | +{ |
| 1188 | +uint8info=xl_info& ~XLR_INFO_MASK; |
| 1189 | + |
| 1190 | +if (info==XLOG_DBASE_CREATE) |
| 1191 | +{ |
| 1192 | +xl_dbase_create_rec*xlrec= (xl_dbase_create_rec*)rec; |
| 1193 | +char*dst_path=xlrec->src_path+strlen(xlrec->src_path)+1; |
| 1194 | + |
| 1195 | +sprintf(buf+strlen(buf),"create db: %u copy \"%s\" to \"%s\"", |
| 1196 | +xlrec->db_id,xlrec->src_path,dst_path); |
| 1197 | +} |
| 1198 | +elseif (info==XLOG_DBASE_DROP) |
| 1199 | +{ |
| 1200 | +xl_dbase_drop_rec*xlrec= (xl_dbase_drop_rec*)rec; |
| 1201 | + |
| 1202 | +sprintf(buf+strlen(buf),"drop db: %u directory: \"%s\"", |
| 1203 | +xlrec->db_id,xlrec->dir_path); |
| 1204 | +} |
| 1205 | +else |
| 1206 | +strcat(buf,"UNKNOWN"); |
| 1207 | +} |