如何让MySQL的UNIX_TIMESTAMP()返回自定义时间戳?
全局修改MySQL所有会话时间戳的解决办法
问题场景
测试流程中,pytest启动my_server和Docker版mysql_server,my_server通过主机网络连接MySQL,执行SELECT UNIX_TIMESTAMP();获取时间戳后转成星期数输出:
('mon', 1667768400), # 输出1 ('tue', 1667854800), # 输出2 ('wed', 1667941200), # 输出3 ...
尝试全局设置时间戳失败,仅能修改当前会话:
-- 当前会话修改有效 mysql> set session timestamp = 1667768400; Query OK, 0 rows affected (0.00 sec) mysql> SELECT UNIX_TIMESTAMP(); +------------------+ | UNIX_TIMESTAMP() | +------------------+ | 1667768400 | +------------------+ 1 row in set (0.00 sec) -- 全局设置报错 mysql> set global timestamp = 1667768400; ERROR 1228 (HY000): Variable 'timestamp' is a SESSION variable and can't be used with SET GLOBAL
约束条件:
- 不能修改
my_server代码,成本过高; - 不能修改主机时间,需要sudo权限不符合测试规范。
可行方案
1. 修改Docker容器内的系统时间(最简方案)
MySQL的UNIX_TIMESTAMP()默认读取系统时间,直接修改Docker容器的时间不会影响主机,完全符合测试规范:
- 找到mysql容器ID:
docker ps | grep mysql_server
- 进入容器修改目标时间(对应1667768400的时间为2022-11-06 00:00:00):
docker exec -it <容器ID> bash date -s "2022-11-06 00:00:00"
- 重启容器内的MySQL服务(部分版本需要刷新时间缓存):
service mysql restart
完成后所有会话的UNIX_TIMESTAMP()都会返回对应时间戳。
2. 用ProxySQL拦截查询并替换结果
不想修改容器时间的话,可通过中间代理拦截SELECT UNIX_TIMESTAMP()请求,直接返回预设值:
- 启动ProxySQL容器,配置后端指向你的
mysql_server; - 将
my_server的数据库连接地址改为ProxySQL的地址; - 在ProxySQL中添加规则替换查询结果:
INSERT INTO mysql_query_rules (rule_id, active, match_pattern, replace_pattern, apply) VALUES (1, 1, '^SELECT UNIX_TIMESTAMP\\(\\);$', 'SELECT 1667768400;', 1); LOAD MYSQL QUERY RULES TO RUNTIME; SAVE MYSQL QUERY RULES TO DISK;
这样my_server获取到的就是预设的时间戳,无需修改原有服务。
3. 自定义MySQL UDF(进阶方案)
如果需要更灵活的全局控制,可以编写自定义UDF替换原生UNIX_TIMESTAMP(),让它读取全局配置的时间戳返回:
- 用C语言编写UDF逻辑,读取全局变量返回指定时间戳;
- 编译成.so文件,放到MySQL插件目录;
- 在MySQL中注册UDF并设置全局变量控制返回值。
该方案适合长期复用场景,但需要编译插件,步骤相对复杂。
内容的提问来源于stack exchange,提问作者oleg
相关产品推荐
相关产品推荐

