firebird icon indicating copy to clipboard operation
firebird copied to clipboard

Fix error when changing force write mode

Open TreeHunter9 opened this issue 1 year ago • 17 comments

When we try to change force write mode on database that has connections, we can get various types of errors or asserts from PIO_ functions (Super Server mode only). These errors can be reproduced using TPCC load and changing force write mode.
This patch fixes cases where someone tries to change force write mode when database has connections. This is done via RWLock for file descriptor, so we can be sure that some other thread won't close this descriptor while we're using it.
For Classic Server we can change force write mode only with no connections.

TreeHunter9 avatar Jun 03 '24 13:06 TreeHunter9

For Classic Server we can change force write mode only with no connections.

Why ?

hvlad avatar Jun 06 '24 08:06 hvlad

For Classic Server we can change force write mode only with no connections.

Why ?

I tried to implement this via AST, looking at LCK_monitor as an example, but I couldn't figure it out where and when I should relock my lock after LCK_downgrade in AST. So I stop on restriction for classic server. Maybe you can give me some advice on this issue?

TreeHunter9 avatar Jun 07 '24 12:06 TreeHunter9

For Classic Server we can change force write mode only with no connections.

Why ?

I tried to implement this via AST, looking at LCK_monitor as an example, but I couldn't figure it out where and when I should relock my lock after LCK_downgrade in AST. So I stop on restriction for classic server. Maybe you can give me some advice on this issue?

My question was - why different CS processes must run with the same FW mode ? I.e. why force same mode here ? I highly doubt it can produce

various types of errors or asserts from PIO_ functions

hvlad avatar Jun 07 '24 12:06 hvlad

why different CS processes must run with the same FW mode ?

I think because it's more expected, if someone changes FW mode, they will expect all connections to change FW mode too. This works with Super, but not with Classic.
But this is how I see it, currently if we change FW mode on Classic, it will not change for already connected users, maybe I should keep this behavior.

I.e. why force same mode here ? I highly doubt it can produce

various types of errors or asserts from PIO_ functions

Yes, these errors can only be reproduced on Super, I should have mentioned that in the PR description, added it now.

TreeHunter9 avatar Jun 07 '24 12:06 TreeHunter9

The more I think about it the more I consider that solution is not fully correct and excessive, sorry.

There is no (direct) harm when different CS processes use different FW mode. It is not perfect, I agree, but we lived with it many years with no complains.

As for SS, where the real problem happens, I think it is not good to re-open database file with a (lot of) user connections - it could lead to a significant performance loss for a visible time, as OS flushes the file buffers when file is closing and it could take a time. Note, all user connections the require disk IO will wait for this process to finish.

So, instead, I offer to save new FW flag value to the header page (all architectures) and re-open file only if there is no other connections (required for SS only, but could be discussed). This is similar to how change of page buffers number works, btw.

hvlad avatar Jun 07 '24 13:06 hvlad

So, instead, I offer to save new FW flag value to the header page (all architectures) and re-open file only if there is no other connections (required for SS only, but could be discussed).

I would expect that while file open mode changes are delayed in this case for SS, changes in page cache flush strategy would be immediate. Perhaps file re-opening also may be immediate if the change is done in sole connection.

aafemt avatar Jun 07 '24 13:06 aafemt

So, instead, I offer to save new FW flag value to the header page (all architectures) and re-open file only if there is no other connections (required for SS only, but could be discussed).

I would expect that while file open mode changes are delayed in this case for SS, changes in page cache flush strategy would be immediate.

Could you show what you means by 'flush strategy', how it works now and how you would expect it to work ?

Perhaps file re-opening also may be immediate if the change is done in sole connection.

This is what I said above.

hvlad avatar Jun 07 '24 14:06 hvlad

Could you show what you means by 'flush strategy', how it works now and how you would expect it to work ?

I expect that when I set FW OFF, dirty pages won't be flushed immediately on commit for all connections. Because that's why I do it.

aafemt avatar Jun 07 '24 14:06 aafemt

My last comment is for SS. CS can do whatever it wants.

aafemt avatar Jun 07 '24 15:06 aafemt

Could you show what you means by 'flush strategy', how it works now and how you would expect it to work ?

I expect that when I set FW OFF, dirty pages won't be flushed immediately on commit for all connections. Because that's why I do it.

When engine works with FW=ON (FIL_force_write flag is set) is doesn't call PIO_flush(), because it makes no sence - OS does it for us on every write().

When engine works with FW=OFF (FIL_force_write flag is not set) is does call PIO_flush() (as often as it allowed by MaxUnflushedWrites and MaxUnflushedWriteTime settings) - this is necessary, as OS doesn't do it.

Now, imagine database with FW=ON and admin changed FW to OFF. File mode is not changed and OS still writes every page to disk immediately. You offer to clear FIL_force_write flag and make engine to call PIO_flush() in addition to the OS immediate writes. In best case it will change nothing, in worst case - adds performance penalty. In any case your expectation about perf boost is wrong.

In opposite case, when FW is changed from OFF to ON, engine will never call PIO_flush() and OS also will not write data to disk immediately. This is very bad for on-disk consistency, obviously.

hvlad avatar Jun 07 '24 15:06 hvlad

as often as it allowed by MaxUnflushedWrites and MaxUnflushedWriteTime settings

Which by default are -1, i.e. "never".

aafemt avatar Jun 07 '24 15:06 aafemt

as often as it allowed by MaxUnflushedWrites and MaxUnflushedWriteTime settings

Which by default are -1, i.e. "never".

Not on Windows. Either way, that doesn't make your expectation/proposal correct.

hvlad avatar Jun 07 '24 15:06 hvlad

As for SS, where the real problem happens, I think it is not good to re-open database file with a (lot of) user connections - it could lead to a significant performance loss for a visible time, as OS flushes the file buffers when file is closing and it could take a time. Note, all user connections the require disk IO will wait for this process to finish.

I guess the main point was when someone changes the FW mode, he usually wants to get the effect immediately. And there are 2 ways to do this: either force all user connections to close or reopen the file with relatively less time and performance penalty. The second one looks better from this point. Also, if we allow the actual FW mode change to be delayed then we cannot trust its status showed by gstat.

This is similar to how change of page buffers number works, btw.

Similarity is good but changing the FW mode is more critical, I believe.

ilya071294 avatar Jun 10 '24 08:06 ilya071294

What I don't like in the "delayed option" is it being unpredictable. DBA turns FW on and expects that crashes will not lead to corruptions after that. The same for CS - if some connections will still be using FW=OFF after that and crash and corrupt the database this is not what DBA expects after changing FW to ON. But they have no idea when the change will be actually applied. So to ensure that they need also to shutdown the database to force everybody to reconnect. This is hardly pleasant under user load. This is the difference between BUFFERS and FW -- one is just about performance but the other is about reliability which is more important, IMO.

dyemanov avatar Jun 10 '24 08:06 dyemanov

What I don't like in the "delayed option" is it being unpredictable. DBA turns FW on and expects that crashes will not lead to corruptions after that. The same for CS - if some connections will still be using FW=OFF after that and crash and corrupt the database this is not what DBA expects after changing FW to ON.

Same for SC.

But they have no idea when the change will be actually applied.

Document it. Issue warning.

So to ensure that they need also to shutdown the database to force everybody to reconnect. This is hardly pleasant under user load.

Explain, please - why reasonable DBA could think about changing FW under real load ever ? What is real necessity for this and how often it happens ?

PS this is again flame about nothing. The original intent was to fix errors on SS when FW is changing under load. But it was not about making any uneducated "want-to-be-dba" happy.

hvlad avatar Jun 10 '24 08:06 hvlad

So, we stop at the realization proposed by @hvlad?

TreeHunter9 avatar Jun 14 '24 06:06 TreeHunter9

So to ensure that they need also to shutdown the database to force everybody to reconnect. This is hardly pleasant under user load.

Explain, please - why reasonable DBA could think about changing FW under real load ever ? What is real necessity for this and how often it happens ?

Why to change FW at all? Loading, indexing, or even just because someone wants. At least untill we don't require EX lock on DB for this. So it should either predictbaly work or not. Moreover, an ability to change FW on the fly looks not so bad option for me, and might be useful for some heavy regilar operations, in combination with nbackup as "global transaction".

romansimakov avatar Jun 14 '24 16:06 romansimakov