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

Commit97b23c4

Browse files
committed
Merge branch 'master' into release_2_5
2 parentsda2cbcb +6e8e948 commit97b23c4

File tree

3 files changed

+107
-43
lines changed

3 files changed

+107
-43
lines changed

‎src/utils/file.c

Lines changed: 39 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -777,6 +777,34 @@ fio_fwrite(FILE* f, void const* buf, size_t size)
777777
returnfwrite(buf,1,size,f);
778778
}
779779

780+
/*
781+
* Write buffer to descriptor by calling write(),
782+
* If size of written data is less than buffer size,
783+
* then try to write what is left.
784+
* We do this to get honest errno if there are some problems
785+
* with filesystem, since writing less than buffer size
786+
* is not considered an error.
787+
*/
788+
staticssize_t
789+
durable_write(intfd,constchar*buf,size_tsize)
790+
{
791+
off_tcurrent_pos=0;
792+
size_tbytes_left=size;
793+
794+
while (bytes_left>0)
795+
{
796+
intrc=write(fd,buf+current_pos,bytes_left);
797+
798+
if (rc <=0)
799+
returnrc;
800+
801+
bytes_left-=rc;
802+
current_pos+=rc;
803+
}
804+
805+
returnsize;
806+
}
807+
780808
/* Write data to the file synchronously */
781809
ssize_t
782810
fio_write(intfd,voidconst*buf,size_tsize)
@@ -806,7 +834,7 @@ fio_write(int fd, void const* buf, size_t size)
806834
}
807835
else
808836
{
809-
returnwrite(fd,buf,size);
837+
returndurable_write(fd,buf,size);
810838
}
811839
}
812840

@@ -816,7 +844,7 @@ fio_write_impl(int fd, void const* buf, size_t size, int out)
816844
intrc;
817845
fio_headerhdr;
818846

819-
rc=write(fd,buf,size);
847+
rc=durable_write(fd,buf,size);
820848

821849
hdr.arg=0;
822850
hdr.size=0;
@@ -838,34 +866,6 @@ fio_fwrite_async(FILE* f, void const* buf, size_t size)
838866
:fwrite(buf,1,size,f);
839867
}
840868

841-
/*
842-
* Write buffer to descriptor by calling write(),
843-
* If size of written data is less than buffer size,
844-
* then try to write what is left.
845-
* We do this to get honest errno if there are some problems
846-
* with filesystem, since writing less than buffer size
847-
* is not considered an error.
848-
*/
849-
staticssize_t
850-
durable_write(intfd,constchar*buf,size_tsize)
851-
{
852-
off_tcurrent_pos=0;
853-
size_tbytes_left=size;
854-
855-
while (bytes_left>0)
856-
{
857-
intrc=write(fd,buf+current_pos,bytes_left);
858-
859-
if (rc <=0)
860-
returnrc;
861-
862-
bytes_left-=rc;
863-
current_pos+=rc;
864-
}
865-
866-
returnsize;
867-
}
868-
869869
/* Write data to the file */
870870
/* TODO: support async report error */
871871
ssize_t
@@ -950,23 +950,22 @@ fio_fwrite_async_compressed(FILE* f, void const* buf, size_t size, int compress_
950950
}
951951
else
952952
{
953-
charuncompressed_buf[BLCKSZ];
954953
char*errormsg=NULL;
955-
int32uncompressed_size=fio_decompress(uncompressed_buf,buf,size,compress_alg,&errormsg);
954+
chardecompressed_buf[BLCKSZ];
955+
int32decompressed_size=fio_decompress(decompressed_buf,buf,size,compress_alg,&errormsg);
956956

957-
if (uncompressed_size<0)
957+
if (decompressed_size<0)
958958
elog(ERROR,"%s",errormsg);
959959

960-
returnfwrite(uncompressed_buf,1,uncompressed_size,f);
960+
returnfwrite(decompressed_buf,1,decompressed_size,f);
961961
}
962962
}
963963

964964
staticvoid
965965
fio_write_compressed_impl(intfd,voidconst*buf,size_tsize,intcompress_alg)
966966
{
967-
intrc;
968-
int32uncompressed_size;
969-
charuncompressed_buf[BLCKSZ];
967+
int32decompressed_size;
968+
chardecompressed_buf[BLCKSZ];
970969

971970
/* If the previous command already have failed,
972971
* then there is no point in bashing a head against the wall
@@ -975,14 +974,12 @@ fio_write_compressed_impl(int fd, void const* buf, size_t size, int compress_alg
975974
return;
976975

977976
/* decompress chunk */
978-
uncompressed_size=fio_decompress(uncompressed_buf,buf,size,compress_alg,&async_errormsg);
977+
decompressed_size=fio_decompress(decompressed_buf,buf,size,compress_alg,&async_errormsg);
979978

980-
if (uncompressed_size<0)
979+
if (decompressed_size<0)
981980
return;
982981

983-
rc=write(fd,uncompressed_buf,uncompressed_size);
984-
985-
if (rc <=0)
982+
if (durable_write(fd,decompressed_buf,decompressed_size) <=0)
986983
{
987984
async_errormsg=pgut_malloc(ERRMSG_MAX_LEN);
988985
snprintf(async_errormsg,ERRMSG_MAX_LEN,"%s",strerror(errno));

‎tests/helpers/ptrack_helpers.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2003,6 +2003,9 @@ def stopped_in_breakpoint(self):
20032003
returnTrue
20042004
returnFalse
20052005

2006+
defquit(self):
2007+
self.proc.terminate()
2008+
20062009
# use for breakpoint, run, continue
20072010
def_execute(self,cmd,running=True):
20082011
output= []

‎tests/restore.py

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
importshutil
1010
importjson
1111
fromshutilimportcopyfile
12-
fromtestgresimportQueryException
12+
fromtestgresimportQueryException,StartNodeException
13+
fromstatimportS_ISDIR
1314

1415

1516
module_name='restore'
@@ -3856,3 +3857,66 @@ def test_concurrent_restore(self):
38563857

38573858
# Clean after yourself
38583859
self.del_test_dir(module_name,fname)
3860+
3861+
# @unittest.skip("skip")
3862+
deftest_restore_issue_313(self):
3863+
"""
3864+
Check that partially restored PostgreSQL instance cannot be started
3865+
"""
3866+
fname=self.id().split('.')[3]
3867+
backup_dir=os.path.join(self.tmp_path,module_name,fname,'backup')
3868+
node=self.make_simple_node(
3869+
base_dir=os.path.join(module_name,fname,'node'),
3870+
set_replication=True,
3871+
initdb_params=['--data-checksums'])
3872+
3873+
self.init_pb(backup_dir)
3874+
self.add_instance(backup_dir,'node',node)
3875+
self.set_archiving(backup_dir,'node',node)
3876+
node.slow_start()
3877+
3878+
# FULL backup
3879+
backup_id=self.backup_node(backup_dir,'node',node)
3880+
node.cleanup()
3881+
3882+
count=0
3883+
filelist=self.get_backup_filelist(backup_dir,'node',backup_id)
3884+
forfileinfilelist:
3885+
# count only nondata files
3886+
ifint(filelist[file]['is_datafile'])==0andint(filelist[file]['size'])>0:
3887+
count+=1
3888+
3889+
node_restored=self.make_simple_node(
3890+
base_dir=os.path.join(module_name,fname,'node_restored'))
3891+
node_restored.cleanup()
3892+
self.restore_node(backup_dir,'node',node_restored)
3893+
3894+
gdb=self.restore_node(backup_dir,'node',node,gdb=True,options=['--progress'])
3895+
gdb.verbose=False
3896+
gdb.set_breakpoint('restore_non_data_file')
3897+
gdb.run_until_break()
3898+
gdb.continue_execution_until_break(count-2)
3899+
gdb.quit()
3900+
3901+
# emulate the user or HA taking care of PG configuration
3902+
forfnameinos.listdir(node_restored.data_dir):
3903+
iffname.endswith('.conf'):
3904+
os.rename(
3905+
os.path.join(node_restored.data_dir,fname),
3906+
os.path.join(node.data_dir,fname))
3907+
3908+
try:
3909+
node.slow_start()
3910+
# we should die here because exception is what we expect to happen
3911+
self.assertEqual(
3912+
1,0,
3913+
"Expecting Error because backup is not fully restored")
3914+
exceptStartNodeExceptionase:
3915+
self.assertIn(
3916+
'Cannot start node',
3917+
e.message,
3918+
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(
3919+
repr(e.message),self.cmd))
3920+
3921+
# Clean after yourself
3922+
self.del_test_dir(module_name,fname)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp