我们最近切换到RDS实例,发现我们的数据库任务比预期提前4小时触发。在进一步调查时,问题是由RDS实例上的默认时区设置(UTC)引起的。由于此设置无法更改,因此我们希望使用此数据库实例在所有应用程序中全局修复代码级别的问题。我尝试使用
将我创建的数据库实例的时区设置为“US / Eastern”set GLOBAL time_zone = 'US/Eastern'" OR
set time_zone = 'US/Eastern'"
但是会产生错误“数据库错误:未知或不正确的时区:'美国/东部'”
你认为我在这里做错了什么?有没有人使用过任何其他解决方案?
答案 0 :(得分:9)
不幸的是,无法在RDS数据库参数组中设置default_timezone,因此您的尝试已经是正确的方向。
$ rds-describe-db-parameters default | grep "time_zone"
DBPARAMETER default_time_zone engine-default string static false
要通过SET GLOBAL设置全局值,您需要具有未作为RDS用户授予的SUPER权限。
设置time_zone的唯一方法是基于每个连接
mysql> SET time_zone = timezone;
在我的机器上,我已经成功地尝试了美国/东部,但我有一个相当老一代的人。
确定您可用的时区登录到您的方框
mysql -h yourboxhost.rds.amazonaws.com -u <youruser> -p
并输入
mysql> SELECT * FROM mysql.time_zone_name;
您应该获得可以在实例上设置的已安装且有效的时区名称列表
+----------------------------------------+--------------+
| Name | Time_zone_id |
+----------------------------------------+--------------+
| Africa/Abidjan | 1 |
| Africa/Accra | 2 |
| Africa/Addis_Ababa | 3 |
| Africa/Algiers | 4 |
| Africa/Asmara | 5 |
| Africa/Asmera | 6 |
| Africa/Bamako | 7 |
| Africa/Bangui | 8 |
| Africa/Banjul | 9 |
| Africa/Bissau | 10 |
| Africa/Blantyre | 11 |
| Africa/Brazzaville | 12 |
| Africa/Bujumbura | 13 |
| Africa/Cairo | 14 |
etc...
每次连接数据库服务器时都必须设置time_zone
例如,如果您使用php Mysqli扩展,则可以执行此操作
$mysqli = mysqli_init();
mysqli_options($mysqli,MYSQLI_INIT_COMMAND,"SET time_zone = 'Africa/Brazzaville'" );
mysqli_real_connect($mysqli,$host, $user, $pass,$dbName) or die ('Unable to connect');
否则只需手动(就数据库连接器而言)在您连接到数据库后立即执行SET time_zone = '<YOUR_DESIRED_TIMEZONE>'
查询
答案 1 :(得分:5)
现在可以修改RDS数据库实例的time_zone设置:https://aws.amazon.com/de/premiumsupport/knowledge-center/rds-change-time-zone/
答案 2 :(得分:3)
tldr;
创建一个所有用户都具有EXECUTE访问权限的“共享”模式,创建一个修改会话时区的SPROC并修改init_connect MySQL参数来调用它。
正如Ryan Weir在他出色的answer in a duplicate question指出的那样,如果可能的话,这应该是可以避免的。但是,如果你像我一样想要为了方便和理智而实施它,那么我就采用了Ryan的解决方案并进行了一些修改。
如果您在MySQL中设置了多个具有不同权限的用户,那么简单地将sproc放在mysql架构中可能会出现问题。为了解决这个问题,我创建了一个名为“shared”的新模式,并为我的所有用户提供了对此模式的EXECUTE访问权限。然后我创建了以下存储过程。
DROP PROCEDURE IF EXISTS shared.store_time_zone;
CREATE PROCEDURE shared.`store_time_zone`()
IF NOT (POSITION('rdsadmin@' IN CURRENT_USER()) = 1) THEN
SET SESSION time_zone = 'US/Pacific';
END IF;
我更喜欢将“US / Pacific”设置为处理夏令时,但您应该对此进行测试,以确保您的MySQL实例首先识别它。只需执行以下查询SET SESSION time_zone = 'US/Pacific';
即可确保其有效。要查找您的时区,请执行SELECT * FROM mysql.time_zone_name;
此时我建议您在修改参数组之前测试权限,并且可能会破坏所有内容。只需连接到数据库(最好是具有低级别权限和/或常用的用户)并执行以下查询。
CALL shared.store_time_zone;
select now();
希望您没有收到任何错误,并显示正确的时间。
接下来,您需要修改RDS实例正在使用的数据库参数组中的init_connect参数。您可以在RDS Web控制台中,通过API或命令行实用程序执行此操作。如果使用命令行,它将如下所示:
$ rds-modify-db-parameter-group PARAMGROUP --parameters "name=init_connect, value='CALL shared.store_time_zone', method=immediate"
如果您通过Web控制台执行此操作,则只需更改init_connect的值即可。
CALL shared.store_time_zone
返回Web控制台中的RDS实例,并将详细信息窗格向下滚动到数据库参数组。它应该说(应用)或(同步)。一旦它(同步)去测试一切,以确保没有问题。
如果此时遇到问题并需要回滚,那么我建议将init_connect值设置为无害的:
SET SESSION time_zone = '-00:00';
从Web控制台无法将其设置为空白。有关一个can't restore the empty value for the DB parameter
的详细信息,请参阅此主题答案 3 :(得分:1)
我做了以下步骤,以便我可以更改时区
登录RDS并创建新参数组。
编辑新创建的参数组
设置时区Ex:亚洲/加尔各答和保存更改
修改RDS实例,将DB的参数组更改为新创建的参数组
保存并重新启动RDS实例
答案 4 :(得分:0)
@Thomas Paine的解决方案适用于我,除了我必须使用user()
而不是current_user()
,因为init_connect
current_user()的上下文返回主RDS用户。 (通过高手我不是指rdsadmin,它是真正的root用户,而是使用具有大多数权限的数据库实例创建的用户。)