!3523 【bugfixed】解决创建表空间,绝对路径不存在时会话卡住,数据库服务无法正常关闭也无法登陆的问题
Merge pull request !3523 from laishenghao/space
This commit is contained in:
@ -100,6 +100,8 @@ static void createtbspc_abort_callback(bool isCommit, const void* arg);
|
||||
|
||||
Datum CanonicalizeTablespaceOptions(Datum datum);
|
||||
|
||||
#define CHECK_PATH_RETRY_COUNT 100
|
||||
|
||||
#define CANONICALIZE_PATH(path) \
|
||||
do { \
|
||||
if (NULL != (path)) { \
|
||||
@ -2478,12 +2480,56 @@ char* get_tablespace_name(Oid spc_oid)
|
||||
return result;
|
||||
}
|
||||
|
||||
bool IsPathContainsSymlink(char* path)
|
||||
{
|
||||
struct stat statbuf;
|
||||
errno_t rc;
|
||||
char* ptr = path;
|
||||
|
||||
if (*ptr == '/') {
|
||||
++ptr;
|
||||
}
|
||||
|
||||
for (bool isLast = false; !isLast; ++ptr) {
|
||||
if (*ptr == '\0') {
|
||||
isLast = true;
|
||||
} else if (*ptr != '/') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isLast && ptr[1] == '\0') {
|
||||
isLast = true;
|
||||
}
|
||||
|
||||
*ptr = '\0';
|
||||
rc = memset_s(&statbuf, sizeof(statbuf), 0, sizeof(statbuf));
|
||||
if (rc != EOK) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (lstat(path, &statbuf) == 0 && S_ISLNK(statbuf.st_mode)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!isLast) {
|
||||
*ptr = '/';
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* check if the dir(location) is exist, if not create it */
|
||||
void check_create_dir(char* location)
|
||||
{
|
||||
int ret;
|
||||
int retryCount = 0;
|
||||
bool hasLink = IsPathContainsSymlink(location);
|
||||
|
||||
recheck:
|
||||
if (hasLink) {
|
||||
++retryCount;
|
||||
}
|
||||
/* We believe that the location we got from the record is credible. */
|
||||
switch (ret = pg_check_dir(location)) {
|
||||
case 0: {
|
||||
@ -2492,6 +2538,14 @@ recheck:
|
||||
if (pg_mkdir_p_used_by_gaussdb(tmplocation, S_IRWXU) == -1) {
|
||||
if (errno == EEXIST) {
|
||||
pfree_ext(tmplocation);
|
||||
|
||||
if (hasLink && retryCount > CHECK_PATH_RETRY_COUNT) {
|
||||
ereport(ERROR, (errmodule(MOD_TBLSPC),
|
||||
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
||||
errmsg("recheck location \"%s\" exeed max times.", location),
|
||||
errdetail("the location contains symbolic link, the linked path likely has been deleted.")));
|
||||
}
|
||||
|
||||
goto recheck;
|
||||
} else
|
||||
ereport(ERROR,
|
||||
|
||||
@ -140,4 +140,11 @@ DROP TABLESPACE testspace;
|
||||
-- symlink location
|
||||
\! mkdir -p @testtablespace@/symlink/sym1
|
||||
\! ln -s @testtablespace@/symlink/sym1 @testtablespace@/symlink/sym2
|
||||
CREATE TABLESPACE test_symlink LOCATION '@testtablespace@/symlink/sym2';
|
||||
CREATE TABLESPACE test_symlink LOCATION '@testtablespace@/symlink/sym2';
|
||||
|
||||
-- check linked path deleted
|
||||
\! mkdir -p @testtablespace@/symlink/will_delete
|
||||
\! ln -s @testtablespace@/symlink/will_delete @testtablespace@/symlink/will_delete_link
|
||||
\! rm -rf @testtablespace@/symlink/will_delete
|
||||
|
||||
CREATE TABLESPACE deleted_symlink LOCATION '@testtablespace@/symlink/will_delete_link/local';
|
||||
|
||||
@ -272,3 +272,10 @@ DROP TABLESPACE testspace;
|
||||
\! ln -s @testtablespace@/symlink/sym1 @testtablespace@/symlink/sym2
|
||||
CREATE TABLESPACE test_symlink LOCATION '@testtablespace@/symlink/sym2';
|
||||
ERROR: location "@testtablespace@/symlink/sym2" is symbolic link
|
||||
-- check linked path deleted
|
||||
\! mkdir -p @testtablespace@/symlink/will_delete
|
||||
\! ln -s @testtablespace@/symlink/will_delete @testtablespace@/symlink/will_delete_link
|
||||
\! rm -rf @testtablespace@/symlink/will_delete
|
||||
CREATE TABLESPACE deleted_symlink LOCATION '@testtablespace@/symlink/will_delete_link/local';
|
||||
ERROR: recheck location "@testtablespace@/symlink/will_delete_link" exeed max times.
|
||||
DETAIL: the location contains symbolic link, the linked path likely has been deleted.
|
||||
|
||||
Reference in New Issue
Block a user