8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-22 18:43:02 +01:00

Fixed CORE-5758: Database is corrupted when conflicting "starting at page" values is specified for secondary files (#147)

* Fixed issue: Database is corrupted when conflicting "starting at page" values is specified for secondary files

* Raise error when conflicting "starting at page" values is specified for secondary database files
This commit is contained in:
Ilya Eremin 2018-09-24 13:16:38 +03:00 committed by Alexander Peshkov
parent daef7ba63f
commit c356791b02
11 changed files with 37 additions and 18 deletions

View File

@ -1834,6 +1834,8 @@ C --
PARAMETER (GDS__plugin_name = 335545210)
INTEGER*4 GDS__parameter_name
PARAMETER (GDS__parameter_name = 335545211)
INTEGER*4 GDS__file_starting_page_err
PARAMETER (GDS__file_starting_page_err = 335545212)
INTEGER*4 GDS__gfix_db_name
PARAMETER (GDS__gfix_db_name = 335740929)
INTEGER*4 GDS__gfix_invalid_sw

View File

@ -1829,6 +1829,8 @@ const
gds_plugin_name = 335545210;
isc_parameter_name = 335545211;
gds_parameter_name = 335545211;
isc_file_starting_page_err = 335545212;
gds_file_starting_page_err = 335545212;
isc_gfix_db_name = 335740929;
gds_gfix_db_name = 335740929;
isc_gfix_invalid_sw = 335740930;

View File

@ -913,6 +913,7 @@ static const struct {
{"ses_reset_tran_rollback", 335545209},
{"plugin_name", 335545210},
{"parameter_name", 335545211},
{"file_starting_page_err", 335545212},
{"gfix_db_name", 335740929},
{"gfix_invalid_sw", 335740930},
{"gfix_incmp_sw", 335740932},

View File

@ -947,6 +947,7 @@ const ISC_STATUS isc_ses_reset_warn = 335545208L;
const ISC_STATUS isc_ses_reset_tran_rollback = 335545209L;
const ISC_STATUS isc_plugin_name = 335545210L;
const ISC_STATUS isc_parameter_name = 335545211L;
const ISC_STATUS isc_file_starting_page_err = 335545212L;
const ISC_STATUS isc_gfix_db_name = 335740929L;
const ISC_STATUS isc_gfix_invalid_sw = 335740930L;
const ISC_STATUS isc_gfix_incmp_sw = 335740932L;
@ -1421,7 +1422,7 @@ const ISC_STATUS isc_trace_switch_user_only = 337182757L;
const ISC_STATUS isc_trace_switch_param_miss = 337182758L;
const ISC_STATUS isc_trace_param_act_notcompat = 337182759L;
const ISC_STATUS isc_trace_mandatory_switch_miss = 337182760L;
const ISC_STATUS isc_err_max = 1365;
const ISC_STATUS isc_err_max = 1366;
#else /* c definitions */
@ -2338,6 +2339,7 @@ const ISC_STATUS isc_err_max = 1365;
#define isc_ses_reset_tran_rollback 335545209L
#define isc_plugin_name 335545210L
#define isc_parameter_name 335545211L
#define isc_file_starting_page_err 335545212L
#define isc_gfix_db_name 335740929L
#define isc_gfix_invalid_sw 335740930L
#define isc_gfix_incmp_sw 335740932L
@ -2812,7 +2814,7 @@ const ISC_STATUS isc_err_max = 1365;
#define isc_trace_switch_param_miss 337182758L
#define isc_trace_param_act_notcompat 337182759L
#define isc_trace_mandatory_switch_miss 337182760L
#define isc_err_max 1365
#define isc_err_max 1366
#endif

View File

@ -916,6 +916,7 @@ Data source : @4"}, /* eds_statement */
{335545209, "Transaction is rolled back due to session reset, all changes are lost"}, /* ses_reset_tran_rollback */
{335545210, "Plugin @1:"}, /* plugin_name */
{335545211, "PARAMETER @1"}, /* parameter_name */
{335545212, "Starting page number for file @1 must be @2 or greater"}, /* file_starting_page_err */
{335740929, "data base file name (@1) already given"}, /* gfix_db_name */
{335740930, "invalid switch @1"}, /* gfix_invalid_sw */
{335740932, "incompatible switch combination"}, /* gfix_incmp_sw */

View File

@ -912,6 +912,7 @@ static const struct {
{335545209, -901}, /* 889 ses_reset_tran_rollback */
{335545210, -901}, /* 890 plugin_name */
{335545211, -901}, /* 891 parameter_name */
{335545212, -901}, /* 892 file_starting_page_err */
{335740929, -901}, /* 1 gfix_db_name */
{335740930, -901}, /* 2 gfix_invalid_sw */
{335740932, -901}, /* 4 gfix_incmp_sw */

View File

@ -912,6 +912,7 @@ static const struct {
{335545209, "01102"}, // 889 ses_reset_tran_rollback
{335545210, "00000"}, // 890 plugin_name
{335545211, "42000"}, // 891 parameter_name
{335545212, "HY000"}, // 892 file_starting_page_err
{335740929, "00000"}, // 1 gfix_db_name
{335740930, "00000"}, // 2 gfix_invalid_sw
{335740932, "00000"}, // 4 gfix_incmp_sw

View File

@ -1841,7 +1841,7 @@ static bool add_file(thread_db* tdbb, SSHORT phase, DeferredWork* work, jrd_tra*
*
**************************************/
USHORT section, shadow_number;
SLONG start, max;
SLONG start, min_start;
SET_TDBB(tdbb);
Database* const dbb = tdbb->getDatabase();
@ -1863,7 +1863,7 @@ static bool add_file(thread_db* tdbb, SSHORT phase, DeferredWork* work, jrd_tra*
case 4:
CCH_flush(tdbb, FLUSH_FINI, 0);
max = PageSpace::maxAlloc(dbb) + 1;
start = PageSpace::maxAlloc(dbb) + 1;
AutoRequest handle;
AutoRequest handle2;
@ -1891,24 +1891,31 @@ static bool add_file(thread_db* tdbb, SSHORT phase, DeferredWork* work, jrd_tra*
END_MODIFY
}
// If there is no starting position specified, or if it is
// too low a value, make a stab at assigning one based on
// the indicated preference for the previous file length.
if ((start = X.RDB$FILE_START) < max)
// Check the previous file length
FOR(REQUEST_HANDLE handle2 TRANSACTION_HANDLE transaction)
FIRST 1 Y IN RDB$FILES
WITH Y.RDB$SHADOW_NUMBER EQ X.RDB$SHADOW_NUMBER
AND Y.RDB$FILE_SEQUENCE NOT MISSING
SORTED BY DESCENDING Y.RDB$FILE_SEQUENCE
{
FOR(REQUEST_HANDLE handle2 TRANSACTION_HANDLE transaction)
FIRST 1 Y IN RDB$FILES
WITH Y.RDB$SHADOW_NUMBER EQ X.RDB$SHADOW_NUMBER
AND Y.RDB$FILE_SEQUENCE NOT MISSING
SORTED BY DESCENDING Y.RDB$FILE_SEQUENCE
if (!Y.RDB$FILE_START.NULL && !Y.RDB$FILE_LENGTH.NULL)
{
start = Y.RDB$FILE_START + Y.RDB$FILE_LENGTH;
min_start = Y.RDB$FILE_START + (Y.RDB$FILE_LENGTH ? Y.RDB$FILE_LENGTH : 1);
start = MAX(min_start, start);
}
END_FOR
}
END_FOR
// If there is no starting position specified, or if it is
// too low a value, raise the error.
if (X.RDB$FILE_START < start)
{
ERR_post(Arg::Gds(isc_file_starting_page_err) <<
Arg::Str(X.RDB$FILE_NAME) << Arg::Num(start));
}
start = MAX(max, start);
start = X.RDB$FILE_START;
shadow_number = X.RDB$SHADOW_NUMBER;
if ((shadow_number &&
(section = SDW_add_file(tdbb, X.RDB$FILE_NAME, start, shadow_number))) ||

View File

@ -1,7 +1,7 @@
/* MAX_NUMBER is the next number to be used, always one more than the highest message number. */
set bulk_insert INSERT INTO FACILITIES (LAST_CHANGE, FACILITY, FAC_CODE, MAX_NUMBER) VALUES (?, ?, ?, ?);
--
('2018-08-31 12:44:00', 'JRD', 0, 892)
('2018-08-31 12:44:00', 'JRD', 0, 893)
('2015-03-17 18:33:00', 'QLI', 1, 533)
('2015-01-07 18:01:51', 'GFIX', 3, 134)
('1996-11-07 13:39:40', 'GPRE', 4, 1)

View File

@ -999,6 +999,7 @@ Data source : @4', NULL, NULL)
('ses_reset_tran_rollback', NULL, 'Attachment.cpp', NULL, 0, 889, NULL, 'Transaction is rolled back due to session reset, all changes are lost', NULL, NULL);
('plugin_name', NULL, 'CryptoManager.cpp', NULL, 0, 890, NULL, 'Plugin @1:', NULL, NULL);
('parameter_name', 'ProcedureManager::checkDependencies', 'dfw.e', NULL, 0, 891, NULL, 'PARAMETER @1', NULL, NULL);
('file_starting_page_err', 'add_file', 'dfw.epp', NULL, 0, 892, NULL, 'Starting page number for file @1 must be @2 or greater', NULL, NULL);
-- QLI
(NULL, NULL, NULL, NULL, 1, 0, NULL, 'expected type', NULL, NULL);
(NULL, NULL, NULL, NULL, 1, 1, NULL, 'bad block type', NULL, NULL);

View File

@ -898,6 +898,7 @@ set bulk_insert INSERT INTO SYSTEM_ERRORS (SQL_CODE, SQL_CLASS, SQL_SUBCLASS, FA
(-901, '01', '102', 0, 889, 'ses_reset_tran_rollback', NULL, 'WARNING')
(-901, '00', '000', 0, 890, 'plugin_name', NULL, NULL)
(-901, '42', '000', 0, 891, 'parameter_name', NULL, NULL)
(-901, 'HY', '000', 0, 892, 'file_starting_page_err', NULL, NULL)
-- GFIX
(-901, '00', '000', 3, 1, 'gfix_db_name', NULL, NULL)
(-901, '00', '000', 3, 2, 'gfix_invalid_sw', NULL, NULL)