mirror of
https://github.com/processone/ejabberd
synced 2025-10-03 17:59:31 +02:00
Add option update_sql_schema_timeout to allow schema update use longer timeouts
This also makes batch of schema updates to single table use transaction, which should help in not leaving table in inconsistent state if some update steps fails (unless you use mysql where you can't rollback changes to table schemas).
This commit is contained in:
parent
f56739fd9f
commit
ead87e3727
4 changed files with 254 additions and 237 deletions
|
@ -164,6 +164,7 @@
|
||||||
-export([sql_username/0, sql_username/1]).
|
-export([sql_username/0, sql_username/1]).
|
||||||
-export([trusted_proxies/0]).
|
-export([trusted_proxies/0]).
|
||||||
-export([update_sql_schema/0]).
|
-export([update_sql_schema/0]).
|
||||||
|
-export([update_sql_schema_timeout/0, update_sql_schema_timeout/1]).
|
||||||
-export([use_cache/0, use_cache/1]).
|
-export([use_cache/0, use_cache/1]).
|
||||||
-export([validate_stream/0]).
|
-export([validate_stream/0]).
|
||||||
-export([version/0]).
|
-export([version/0]).
|
||||||
|
@ -1109,6 +1110,13 @@ trusted_proxies() ->
|
||||||
update_sql_schema() ->
|
update_sql_schema() ->
|
||||||
ejabberd_config:get_option({update_sql_schema, global}).
|
ejabberd_config:get_option({update_sql_schema, global}).
|
||||||
|
|
||||||
|
-spec update_sql_schema_timeout() -> 'infinity' | pos_integer().
|
||||||
|
update_sql_schema_timeout() ->
|
||||||
|
update_sql_schema_timeout(global).
|
||||||
|
-spec update_sql_schema_timeout(global | binary()) -> 'infinity' | pos_integer().
|
||||||
|
update_sql_schema_timeout(Host) ->
|
||||||
|
ejabberd_config:get_option({update_sql_schema_timeout, Host}).
|
||||||
|
|
||||||
-spec use_cache() -> boolean().
|
-spec use_cache() -> boolean().
|
||||||
use_cache() ->
|
use_cache() ->
|
||||||
use_cache(global).
|
use_cache(global).
|
||||||
|
|
|
@ -264,6 +264,8 @@ opt_type(new_sql_schema) ->
|
||||||
econf:bool();
|
econf:bool();
|
||||||
opt_type(update_sql_schema) ->
|
opt_type(update_sql_schema) ->
|
||||||
econf:bool();
|
econf:bool();
|
||||||
|
opt_type(update_sql_schema_timeout) ->
|
||||||
|
econf:timeout(second, infinity);
|
||||||
opt_type(oauth_access) ->
|
opt_type(oauth_access) ->
|
||||||
econf:acl();
|
econf:acl();
|
||||||
opt_type(oauth_cache_life_time) ->
|
opt_type(oauth_cache_life_time) ->
|
||||||
|
@ -613,6 +615,7 @@ options() ->
|
||||||
{net_ticktime, timer:seconds(60)},
|
{net_ticktime, timer:seconds(60)},
|
||||||
{new_sql_schema, ?USE_NEW_SQL_SCHEMA_DEFAULT},
|
{new_sql_schema, ?USE_NEW_SQL_SCHEMA_DEFAULT},
|
||||||
{update_sql_schema, true},
|
{update_sql_schema, true},
|
||||||
|
{update_sql_schema_timeout, timer:minutes(5)},
|
||||||
{oauth_access, none},
|
{oauth_access, none},
|
||||||
{oauth_cache_life_time,
|
{oauth_cache_life_time,
|
||||||
fun(Host) -> ejabberd_config:get_option({cache_life_time, Host}) end},
|
fun(Host) -> ejabberd_config:get_option({cache_life_time, Host}) end},
|
||||||
|
|
|
@ -929,6 +929,12 @@ doc() ->
|
||||||
"This option was added in ejabberd 23.10, "
|
"This option was added in ejabberd 23.10, "
|
||||||
"and enabled by default since 24.06. "
|
"and enabled by default since 24.06. "
|
||||||
"The default value is 'true'.")}},
|
"The default value is 'true'.")}},
|
||||||
|
{update_sql_schema_timeout,
|
||||||
|
#{value => "timeout()",
|
||||||
|
note => "added in 24.07",
|
||||||
|
desc =>
|
||||||
|
?T("Time allocated to SQL schema update queries. "
|
||||||
|
"The default value is set to 5 minutes.")}},
|
||||||
{oauth_access,
|
{oauth_access,
|
||||||
#{value => ?T("AccessName"),
|
#{value => ?T("AccessName"),
|
||||||
desc => ?T("By default creating OAuth tokens is not allowed. "
|
desc => ?T("By default creating OAuth tokens is not allowed. "
|
||||||
|
|
|
@ -226,6 +226,13 @@ store_version(Host, Module, Version) ->
|
||||||
["!module=%(SModule)s",
|
["!module=%(SModule)s",
|
||||||
"version=%(Version)d"]).
|
"version=%(Version)d"]).
|
||||||
|
|
||||||
|
store_version_t(Module, Version) ->
|
||||||
|
SModule = misc:atom_to_binary(Module),
|
||||||
|
?SQL_UPSERT_T(
|
||||||
|
"schema_version",
|
||||||
|
["!module=%(SModule)s",
|
||||||
|
"version=%(Version)d"]).
|
||||||
|
|
||||||
table_exists(Host, Table) ->
|
table_exists(Host, Table) ->
|
||||||
ejabberd_sql:sql_query(
|
ejabberd_sql:sql_query(
|
||||||
Host,
|
Host,
|
||||||
|
@ -398,9 +405,7 @@ get_current_version(Host, Module, Schemas) ->
|
||||||
Version
|
Version
|
||||||
end.
|
end.
|
||||||
|
|
||||||
sqlite_table_copy(Host, SchemaInfo, Table) ->
|
sqlite_table_copy_t(SchemaInfo, Table) ->
|
||||||
ejabberd_sql:sql_transaction(Host,
|
|
||||||
fun() ->
|
|
||||||
TableName = Table#sql_table.name,
|
TableName = Table#sql_table.name,
|
||||||
NewTableName = <<"new_", TableName/binary>>,
|
NewTableName = <<"new_", TableName/binary>>,
|
||||||
NewTable = Table#sql_table{name = NewTableName},
|
NewTable = Table#sql_table{name = NewTableName},
|
||||||
|
@ -418,8 +423,7 @@ sqlite_table_copy(Host, SchemaInfo, Table) ->
|
||||||
" RENAME TO ", TableName/binary>>,
|
" RENAME TO ", TableName/binary>>,
|
||||||
?INFO_MSG("Renameing table ~s to ~s:~n~s~n",
|
?INFO_MSG("Renameing table ~s to ~s:~n~s~n",
|
||||||
[NewTableName, TableName, SQL4]),
|
[NewTableName, TableName, SQL4]),
|
||||||
ejabberd_sql:sql_query_t(SQL4)
|
ejabberd_sql:sql_query_t(SQL4).
|
||||||
end).
|
|
||||||
|
|
||||||
format_type(#sql_schema_info{db_type = pgsql}, Column) ->
|
format_type(#sql_schema_info{db_type = pgsql}, Column) ->
|
||||||
case Column#sql_column.type of
|
case Column#sql_column.type of
|
||||||
|
@ -875,6 +879,7 @@ update_schema(Host, Module, RawSchemas) ->
|
||||||
end.
|
end.
|
||||||
|
|
||||||
do_update_schema(Host, Module, SchemaInfo, Schema) ->
|
do_update_schema(Host, Module, SchemaInfo, Schema) ->
|
||||||
|
F = fun() ->
|
||||||
lists:foreach(
|
lists:foreach(
|
||||||
fun({add_column, TableName, ColumnName}) ->
|
fun({add_column, TableName, ColumnName}) ->
|
||||||
{value, Table} =
|
{value, Table} =
|
||||||
|
@ -884,8 +889,7 @@ do_update_schema(Host, Module, SchemaInfo, Schema) ->
|
||||||
lists:keysearch(
|
lists:keysearch(
|
||||||
ColumnName, #sql_column.name, Table#sql_table.columns),
|
ColumnName, #sql_column.name, Table#sql_table.columns),
|
||||||
Res =
|
Res =
|
||||||
ejabberd_sql:sql_query(
|
ejabberd_sql:sql_query_t(
|
||||||
Host,
|
|
||||||
fun(DBType, _DBVersion) ->
|
fun(DBType, _DBVersion) ->
|
||||||
Def = format_column_def(SchemaInfo, Column),
|
Def = format_column_def(SchemaInfo, Column),
|
||||||
Default = format_default(SchemaInfo, Column),
|
Default = format_default(SchemaInfo, Column),
|
||||||
|
@ -924,8 +928,7 @@ do_update_schema(Host, Module, SchemaInfo, Schema) ->
|
||||||
end;
|
end;
|
||||||
({drop_column, TableName, ColumnName}) ->
|
({drop_column, TableName, ColumnName}) ->
|
||||||
Res =
|
Res =
|
||||||
ejabberd_sql:sql_query(
|
ejabberd_sql:sql_query_t(
|
||||||
Host,
|
|
||||||
fun(_DBType, _DBVersion) ->
|
fun(_DBType, _DBVersion) ->
|
||||||
SQL = [<<"ALTER TABLE ">>,
|
SQL = [<<"ALTER TABLE ">>,
|
||||||
TableName,
|
TableName,
|
||||||
|
@ -965,8 +968,7 @@ do_update_schema(Host, Module, SchemaInfo, Schema) ->
|
||||||
#{ignore := true} -> ok;
|
#{ignore := true} -> ok;
|
||||||
_ ->
|
_ ->
|
||||||
Res =
|
Res =
|
||||||
ejabberd_sql:sql_query(
|
ejabberd_sql:sql_query_t(
|
||||||
Host,
|
|
||||||
fun() ->
|
fun() ->
|
||||||
case Index#sql_index.meta of
|
case Index#sql_index.meta of
|
||||||
#{primary_key := true} ->
|
#{primary_key := true} ->
|
||||||
|
@ -1016,7 +1018,7 @@ do_update_schema(Host, Module, SchemaInfo, Schema) ->
|
||||||
Res =
|
Res =
|
||||||
case SchemaInfo#sql_schema_info.db_type of
|
case SchemaInfo#sql_schema_info.db_type of
|
||||||
sqlite ->
|
sqlite ->
|
||||||
sqlite_table_copy(Host, SchemaInfo, Table);
|
sqlite_table_copy_t(SchemaInfo, Table);
|
||||||
pgsql ->
|
pgsql ->
|
||||||
TableName = Table#sql_table.name,
|
TableName = Table#sql_table.name,
|
||||||
SQL1 = [<<"ALTER TABLE ">>, TableName, <<" DROP CONSTRAINT ",
|
SQL1 = [<<"ALTER TABLE ">>, TableName, <<" DROP CONSTRAINT ",
|
||||||
|
@ -1031,8 +1033,7 @@ do_update_schema(Host, Module, SchemaInfo, Schema) ->
|
||||||
[Table#sql_table.name,
|
[Table#sql_table.name,
|
||||||
Index#sql_index.columns,
|
Index#sql_index.columns,
|
||||||
SQL]),
|
SQL]),
|
||||||
ejabberd_sql:sql_query(
|
ejabberd_sql:sql_query_t(
|
||||||
Host,
|
|
||||||
fun(_DBType, _DBVersion) ->
|
fun(_DBType, _DBVersion) ->
|
||||||
ejabberd_sql:sql_query_t(SQL)
|
ejabberd_sql:sql_query_t(SQL)
|
||||||
end);
|
end);
|
||||||
|
@ -1052,8 +1053,7 @@ do_update_schema(Host, Module, SchemaInfo, Schema) ->
|
||||||
[Table#sql_table.name,
|
[Table#sql_table.name,
|
||||||
Index#sql_index.columns,
|
Index#sql_index.columns,
|
||||||
SQL]),
|
SQL]),
|
||||||
ejabberd_sql:sql_query(
|
ejabberd_sql:sql_query_t(
|
||||||
Host,
|
|
||||||
fun(_DBType, _DBVersion) ->
|
fun(_DBType, _DBVersion) ->
|
||||||
ejabberd_sql:sql_query_t(SQL)
|
ejabberd_sql:sql_query_t(SQL)
|
||||||
end)
|
end)
|
||||||
|
@ -1081,8 +1081,7 @@ do_update_schema(Host, Module, SchemaInfo, Schema) ->
|
||||||
[TableName, Columns]);
|
[TableName, Columns]);
|
||||||
{ok, IndexName} ->
|
{ok, IndexName} ->
|
||||||
Res =
|
Res =
|
||||||
ejabberd_sql:sql_query(
|
ejabberd_sql:sql_query_t(
|
||||||
Host,
|
|
||||||
fun(DBType, _DBVersion) ->
|
fun(DBType, _DBVersion) ->
|
||||||
SQL =
|
SQL =
|
||||||
case DBType of
|
case DBType of
|
||||||
|
@ -1112,8 +1111,9 @@ do_update_schema(Host, Module, SchemaInfo, Schema) ->
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end, Schema#sql_schema.update),
|
end, Schema#sql_schema.update),
|
||||||
store_version(Host, Module, Schema#sql_schema.version).
|
store_version_t(Module, Schema#sql_schema.version)
|
||||||
|
end,
|
||||||
|
ejabberd_sql:sql_transaction(Host, F, ejabberd_option:update_sql_schema_timeout(), 1).
|
||||||
|
|
||||||
print_schema(SDBType, SDBVersion, SNewSchema) ->
|
print_schema(SDBType, SDBVersion, SNewSchema) ->
|
||||||
{DBType, DBVersion} =
|
{DBType, DBVersion} =
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue