- Notifications
You must be signed in to change notification settings - Fork16
Resolve issues #5 and #1: reduce number of collisions in the ptrack map#6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
Changes fromall commits
dd6fdc0
829f96c
3026be9
cf8e309
fbfba8c
ab17447
9c132a3
File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading.Please reload this page.
Jump to
Uh oh!
There was an error while loading.Please reload this page.
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,4 @@ | ||
.deps | ||
*.so | ||
*.o | ||
Dockerfile | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -156,6 +156,8 @@ ptrackMapInit(void) | ||
sprintf(ptrack_path, "%s/%s", DataDir, PTRACK_PATH); | ||
sprintf(ptrack_mmap_path, "%s/%s", DataDir, PTRACK_MMAP_PATH); | ||
ptrack_map_reinit: | ||
/* Remove old PTRACK_MMAP_PATH file, if exists */ | ||
if (ptrack_file_exists(ptrack_mmap_path)) | ||
durable_unlink(ptrack_mmap_path, LOG); | ||
@@ -175,18 +177,15 @@ ptrackMapInit(void) | ||
if (stat(ptrack_path, &stat_buf) == 0) | ||
{ | ||
copy_file(ptrack_path, ptrack_mmap_path); | ||
is_new_map = false;/* flag to checkmap file format andchecksum */ | ||
ptrack_fd = BasicOpenFile(ptrack_mmap_path, O_RDWR | PG_BINARY); | ||
} | ||
else | ||
/* Create new file for PTRACK_MMAP_PATH */ | ||
ptrack_fd = BasicOpenFile(ptrack_mmap_path, O_RDWR | O_CREAT | PG_BINARY); | ||
if (ptrack_fd < 0) | ||
elog(ERROR, "ptrack init: failed to open map file \"%s\": %m", ptrack_mmap_path); | ||
#ifdef WIN32 | ||
{ | ||
@@ -227,7 +226,20 @@ ptrackMapInit(void) | ||
elog(ERROR, "ptrack init: wrong map format of file \"%s\"", ptrack_path); | ||
/* Check ptrack version inside old ptrack map */ | ||
if (ptrack_map->version_num != PTRACK_VERSION_NUM) | ||
{ | ||
ereport(WARNING, | ||
(errcode(ERRCODE_DATA_CORRUPTED), | ||
errmsg("ptrack init: map format version %d in the file \"%s\" is incompatible with loaded version %d", | ||
ptrack_map->version_num, ptrack_path, PTRACK_VERSION_NUM), | ||
errdetail("Deleting file \"%s\" and reinitializing ptrack map.", ptrack_path))); | ||
/* Clean up everything and try again */ | ||
ptrackCleanFilesAndMap(); | ||
is_new_map = true; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Не могу найти, где делается unmap в этом случае? Наверное есть смысл позвать здесь There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Да, похоже на то. Я сомневался в этом месте, но потом забыл и не разобрался до конца | ||
goto ptrack_map_reinit; | ||
} | ||
/* Check CRC */ | ||
INIT_CRC32C(crc); | ||
@@ -378,7 +390,7 @@ ptrackCheckpoint(void) | ||
/* | ||
* We are writing ptrack map values to file, but we want to simply map it | ||
* into the memory with mmap after a crash/restart. That way, we have to | ||
* write values taking into account all paddings/alignments. | ||
* | ||
* Write both magic and varsion_num at once. | ||
*/ | ||
@@ -435,7 +447,7 @@ ptrackCheckpoint(void) | ||
* going to overflow. */ | ||
/* | ||
* We should not have anyalignment issues here, since sizeof() | ||
* takes into account all paddings for us. | ||
*/ | ||
ptrack_write_chunk(ptrack_tmp_fd, &crc, (char *) buf, writesz); | ||
@@ -446,7 +458,7 @@ ptrackCheckpoint(void) | ||
} | ||
} | ||
/* Write ifanything left */ | ||
if ((i + 1) % PTRACK_BUF_SIZE != 0) | ||
{ | ||
size_twritesz = sizeof(pg_atomic_uint64) * j; | ||
@@ -641,48 +653,56 @@ void | ||
ptrack_mark_block(RelFileNodeBackend smgr_rnode, | ||
ForkNumber forknum, BlockNumber blocknum) | ||
{ | ||
PtBlockIdbid; | ||
size_thash; | ||
size_tslot1; | ||
size_tslot2; | ||
XLogRecPtrnew_lsn; | ||
/* | ||
* We use pg_atomic_uint64 here only for alignment purposes, because | ||
* pg_atomic_uint64 isforcedly aligned on 8 bytes during the MSVC build. | ||
*/ | ||
pg_atomic_uint64old_lsn; | ||
pg_atomic_uint64old_init_lsn; | ||
if (ptrack_map_size == 0 | ||
|| ptrack_map == NULL | ||
|| smgr_rnode.backend != InvalidBackendId) /* do not track temporary | ||
* relations */ | ||
return; | ||
bid.relnode = smgr_rnode.node; | ||
bid.forknum = forknum; | ||
bid.blocknum = blocknum; | ||
hash = BID_HASH_FUNC(bid); | ||
slot1 = hash % PtrackContentNblocks; | ||
slot2 = ((hash << 32) | (hash >> 32)) % PtrackContentNblocks; | ||
if (RecoveryInProgress()) | ||
new_lsn = GetXLogReplayRecPtr(NULL); | ||
else | ||
new_lsn = GetXLogInsertRecPtr(); | ||
/* Atomically assign new init LSN value */ | ||
old_init_lsn.value = pg_atomic_read_u64(&ptrack_map->init_lsn); | ||
if (old_init_lsn.value == InvalidXLogRecPtr) | ||
{ | ||
elog(DEBUG1, "ptrack_mark_block: init_lsn " UINT64_FORMAT " <- " UINT64_FORMAT, old_init_lsn.value, new_lsn); | ||
while (old_init_lsn.value < new_lsn && | ||
!pg_atomic_compare_exchange_u64(&ptrack_map->init_lsn, (uint64 *) &old_init_lsn.value, new_lsn)); | ||
} | ||
/* Atomically assign new LSN value to the first slot */ | ||
old_lsn.value = pg_atomic_read_u64(&ptrack_map->entries[slot1]); | ||
elog(DEBUG3, "ptrack_mark_block: map[%zu]=" UINT64_FORMAT " <- " UINT64_FORMAT, slot1, old_lsn.value, new_lsn); | ||
while (old_lsn.value < new_lsn && | ||
!pg_atomic_compare_exchange_u64(&ptrack_map->entries[slot1], (uint64 *) &old_lsn.value, new_lsn)); | ||
elog(DEBUG3, "ptrack_mark_block: map[%zu]=" UINT64_FORMAT, hash, pg_atomic_read_u64(&ptrack_map->entries[slot1])); | ||
/* And to the second */ | ||
old_lsn.value = pg_atomic_read_u64(&ptrack_map->entries[slot2]); | ||
while (old_lsn.value < new_lsn && | ||
!pg_atomic_compare_exchange_u64(&ptrack_map->entries[slot2], (uint64 *) &old_lsn.value, new_lsn)); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
/* ptrack/ptrack--2.1--2.2.sql */ | ||
-- Complain if script is sourced in psql, rather than via ALTER EXTENSION | ||
\echo Use "ALTER EXTENSION ptrack UPDATE;" to load this file.\ quit | ||
DROP FUNCTION ptrack_get_pagemapset(start_lsn pg_lsn); | ||
CREATE FUNCTION ptrack_get_pagemapset(start_lsn pg_lsn) | ||
RETURNS TABLE (pathtext, | ||
pagecountbigint, | ||
pagemapbytea) | ||
AS 'MODULE_PATHNAME' | ||
LANGUAGE C STRICT VOLATILE; | ||
CREATE FUNCTION ptrack_get_change_stat(start_lsn pg_lsn) | ||
RETURNS TABLE ( | ||
files bigint, | ||
pages numeric, | ||
"size, MB" numeric | ||
) AS | ||
$func$ | ||
DECLARE | ||
block_size bigint; | ||
BEGIN | ||
block_size := (SELECT setting FROM pg_settings WHERE name = 'block_size'); | ||
RETURN QUERY | ||
SELECT changed_files, | ||
changed_pages, | ||
block_size * changed_pages / (1024.0 * 1024) | ||
FROM | ||
(SELECT count(path) AS changed_files, | ||
sum(pagecount) AS changed_pages | ||
FROM ptrack_get_pagemapset(start_lsn)) s; | ||
END | ||
$func$ LANGUAGE plpgsql; |
Uh oh!
There was an error while loading.Please reload this page.