Commit 191ceaff authored by unknown's avatar unknown

postmerge changes.

parent 18d408a9
...@@ -2266,7 +2266,7 @@ static my_bool translog_buffer_flush(struct st_translog_buffer *buffer) ...@@ -2266,7 +2266,7 @@ static my_bool translog_buffer_flush(struct st_translog_buffer *buffer)
Send page by page in the pagecache what we are going to write on the Send page by page in the pagecache what we are going to write on the
disk disk
*/ */
file.file= buffer->file; file= buffer->file;
for (i= 0, pg= LSN_OFFSET(buffer->offset) / TRANSLOG_PAGE_SIZE; for (i= 0, pg= LSN_OFFSET(buffer->offset) / TRANSLOG_PAGE_SIZE;
i < buffer->size; i < buffer->size;
i+= TRANSLOG_PAGE_SIZE, pg++) i+= TRANSLOG_PAGE_SIZE, pg++)
...@@ -2407,6 +2407,68 @@ translog_dummy_callback(__attribute__((unused)) uchar *page, ...@@ -2407,6 +2407,68 @@ translog_dummy_callback(__attribute__((unused)) uchar *page,
} }
/**
@brief Checks and removes sector protection.
@param page reference on the page content.
@param file transaction log descriptor.
@retvat 0 OK
@retval 1 Error
*/
static my_bool
translog_check_sector_protection(uchar *page, TRANSLOG_FILE *file)
{
uint i, offset;
uchar *table= page + page_overhead[page[TRANSLOG_PAGE_FLAGS]] -
TRANSLOG_PAGE_SIZE / DISK_DRIVE_SECTOR_SIZE; ;
uint8 current= table[0];
DBUG_ENTER("translog_check_sector_protection");
for (i= 1, offset= DISK_DRIVE_SECTOR_SIZE;
i < TRANSLOG_PAGE_SIZE / DISK_DRIVE_SECTOR_SIZE;
i++, offset+= DISK_DRIVE_SECTOR_SIZE)
{
/*
TODO: add chunk counting for "suspecting" sectors (difference is
more than 1-2), if difference more then present chunks then it is
the problem.
*/
uint8 test= page[offset];
DBUG_PRINT("info", ("sector: #%u offset: %u current: %lx "
"read: 0x%x stored: 0x%x%x",
i, offset, (ulong) current,
(uint) uint2korr(page + offset), (uint) table[i],
(uint) table[i + 1]));
/*
3 is minimal possible record length. So we can have "distance"
between 2 sectors value more then DISK_DRIVE_SECTOR_SIZE / 3
only if it is old value, i.e. the sector was not written.
*/
if (((test < current) &&
(0xFFL - current + test > DISK_DRIVE_SECTOR_SIZE / 3)) ||
((test >= current) &&
(test - current > DISK_DRIVE_SECTOR_SIZE / 3)))
{
if (translog_recover_page_up_to_sector(page, offset))
DBUG_RETURN(1);
file->was_recovered= 1;
DBUG_RETURN(0);
}
/* Restore value on the page */
page[offset]= table[i];
current= test;
DBUG_PRINT("info", ("sector: #%u offset: %u current: %lx "
"read: 0x%x stored: 0x%x",
i, offset, (ulong) current,
(uint) page[offset], (uint) table[i]));
}
DBUG_RETURN(0);
}
/** /**
@brief Log page validator (read callback) @brief Log page validator (read callback)
...@@ -2476,50 +2538,10 @@ static my_bool translog_page_validator(uchar *page, ...@@ -2476,50 +2538,10 @@ static my_bool translog_page_validator(uchar *page,
} }
page_pos+= CRC_SIZE; /* Skip crc */ page_pos+= CRC_SIZE; /* Skip crc */
} }
if (flags & TRANSLOG_SECTOR_PROTECTION) if (flags & TRANSLOG_SECTOR_PROTECTION &&
{ translog_check_sector_protection(page, data))
uint i, offset;
uchar *table= page_pos;
uint8 current= table[0];
for (i= 1, offset= DISK_DRIVE_SECTOR_SIZE;
i < TRANSLOG_PAGE_SIZE / DISK_DRIVE_SECTOR_SIZE;
i++, offset+= DISK_DRIVE_SECTOR_SIZE)
{
/*
TODO: add chunk counting for "suspecting" sectors (difference is
more than 1-2), if difference more then present chunks then it is
the problem.
*/
uint8 test= page[offset];
DBUG_PRINT("info", ("sector: #%u offset: %u current: %lx "
"read: 0x%x stored: 0x%x%x",
i, offset, (ulong) current,
(uint) uint2korr(page + offset), (uint) table[i],
(uint) table[i + 1]));
/*
3 is minimal possible record length. So we can have "distance"
between 2 sectors value more then DISK_DRIVE_SECTOR_SIZE / 3
only if it is old value, i.e. the sector was not written.
*/
if (((test < current) &&
(0xFFL - current + test > DISK_DRIVE_SECTOR_SIZE / 3)) ||
((test >= current) &&
(test - current > DISK_DRIVE_SECTOR_SIZE / 3)))
{ {
if (translog_recover_page_up_to_sector(page, offset))
DBUG_RETURN(1); DBUG_RETURN(1);
data->was_recovered= 1;
DBUG_RETURN(0);
}
/* Restore value on the page */
page[offset]= table[i];
current= test;
DBUG_PRINT("info", ("sector: #%u offset: %u current: %lx "
"read: 0x%x stored: 0x%x",
i, offset, (ulong) current,
(uint) page[offset], (uint) table[i]));
}
} }
DBUG_RETURN(0); DBUG_RETURN(0);
} }
...@@ -2729,15 +2751,14 @@ static uchar *translog_get_page(TRANSLOG_VALIDATOR_DATA *data, uchar *buffer, ...@@ -2729,15 +2751,14 @@ static uchar *translog_get_page(TRANSLOG_VALIDATOR_DATA *data, uchar *buffer,
} }
file= get_logfile_by_number(file_no); file= get_logfile_by_number(file_no);
buffer= buffer=
(uchar*) pagecache_valid_read(log_descriptor.pagecache, &file->handler, (uchar*) pagecache_read(log_descriptor.pagecache, &file->handler,
LSN_OFFSET(addr) / TRANSLOG_PAGE_SIZE, LSN_OFFSET(addr) / TRANSLOG_PAGE_SIZE,
3, (direct_link ? NULL : (char*) buffer), 3, (direct_link ? NULL : (char*) buffer),
PAGECACHE_PLAIN_PAGE, PAGECACHE_PLAIN_PAGE,
(direct_link ? (direct_link ?
PAGECACHE_LOCK_READ : PAGECACHE_LOCK_READ :
PAGECACHE_LOCK_LEFT_UNLOCKED), PAGECACHE_LOCK_LEFT_UNLOCKED),
direct_link, direct_link);
&translog_page_validator, (uchar*) data);
DBUG_PRINT("info", ("Direct link is assigned to : 0x%lx * 0x%lx", DBUG_PRINT("info", ("Direct link is assigned to : 0x%lx * 0x%lx",
(ulong) direct_link, (ulong) direct_link,
(ulong)(direct_link ? *direct_link : NULL))); (ulong)(direct_link ? *direct_link : NULL)));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment