麒麟v10 上部署 TiDB v5.1.2 生产环境优化实践
1417
2023-04-11
用docker启动 postgres 数据库
1 项目地址
2 使用情景
一些项目功能会涉及到数据库和代码逻辑的修改,对于数据库的修改,虽然 gorm 之类的工具能够在代码里面适配大部分情况,但是不能覆盖所有数据库变更情况,而且也不够清晰。为清楚表示某次代码提交设计的数据库的修改并且方便 devops 部署服务,可以使用 golang-migrate 这样的工具明确的标识对于数据的某次修改,可以对这些修改做部署和回滚。
使用 golang-migrate 有两种方式,一种是使用 migrate 提供的 CLI,一种是使用 golang library。本次测试使用 migrate CLI。
2.1 支持数据库类型
Source drivers: github-ee, godoc-vfs, s3, bitbucket, go-bindata, gcs, file, github, gitlab
Database drivers: cockroachdb, firebird, postgresql, redshift, clickhouse, postgres, cockroach, firebirdsql, mysql, crdb-postgres, mongodb, mongodb+srv, neo4j, pgx, spanner, sqlserver, stub, cassandra
3 使用方法
3.1 安装 migrate CLI
3.1.1 参考
3.1.2 安装
3.2 postgres 测试
3.2.1 参考
3.2.2 启动 postgres 数据库
在 192.168.10.212 这台测试服务器上用 docker 启动 postgres 数据库
dockerrun--namepostgres-ePOSTGRES_PASSWORD=mysecretpassword-dpostgres:14.0
进入 postgres 容器运行 psql -h localhost -U postgres -w -c "create database example;"来创建 example 数据库。
3.2.3 创建某次数据库变更的 sql 文件
migrate create -ext sql -dir ./migrations -seq create_users_table
这个命令会在 migrations 目录下生成两个文件000001_create_users_table.up.sql 和000001_create_users_table.down.sql , 000001 是某次修改的版本号,000001_create_users_table.up.sql 用来存放创建 users 表的 sql 脚本,000001_create_users_table.down.sql 用来存放回滚这次操作的 sql 脚本。migrate create 命令只负责创建文件,sql 文件的内容需要我们手动编辑。
migrations├── 000001_create_users_table.down.sql├── 000001_create_users_table.up.sql
编辑000001_create_users_table.up.sql
编辑000001_create_users_table.down.sql
DROP TABLE IF EXISTS users;
3.2.4 应用某次数据库修改
migrate 的 up 子命令用来应用某一次数据库变更, down 子命令用来回滚数据库变更操作。
比如 up [N], N 表示执行多少个数据库变更任务,那具体是执行 ./migrations 下面的哪些 sql 脚本呢?
up [N] Apply all or N up migrations down [N] [-all] Apply all or N down migrations Use -all to apply all down migrations
首次执行 migrate up 命令后,会在数据库中添加 schema_migrations 表,这个表有两个字段:version 和 dirty,version 用来表示当前数据库对应 ./migrations 下面的那个版本,比如第一次执行 migrate up 1 后,如果执行成功了, schema_migrations 表中的 version=1,说明当前数据库对应的是000001_create_users_table.up.sql 这个版本 dirty=f(false),执行到 version=1 这次的变更没有出错。如果 dirty=t(true) 会涉及要怎么修复这个错误的问题。
3.2.4.1 首次执行 migrate up
migrate -database 'postgres://postgres:mysecretpassword@192.168.10.212:5432/example?sslmode=disable' -path ./migrations up 11/u create_users_table (47.755135ms)
执行 migrate up 后,数据库中增加了 users 表和 schema_migrations 表
example=# d List of relations Schema | Name | Type | Owner--------+-------------------+----------+---------- public | schema_migrations | table | postgres public | users | table | postgres public | users_user_id_seq | sequence | postgres(3 rows)example=# d users; Table "public.users" Column | Type | Collation | Nullable | Default----------+------------------------+-----------+----------+---------------------------------------- user_id | integer | | not null | nextval('users_user_id_seq'::regclass) username | character varying(50) | | not null | password | character varying(50) | | not null | email | character varying(300) | | not null |Indexes: "users_pkey" PRIMARY KEY, btree (user_id) "users_email_key" UNIQUE CONSTRAINT, btree (email) "users_username_key" UNIQUE CONSTRAINT, btree (username)
example=# select * from schema_migrations; version | dirty---------+------- 1 | f(1 row)
3.2.4.2 回滚操作
migrate -database 'postgres://postgres:mysecretpassword@192.168.10.212:5432/example?sslmode=disable' -path ./migrations downAre you sure you want to apply all down migrations? [y/N]yApplying all down migrations1/d create_users_table (31.550358ms)
migrations down 后,数据库恢复到应用 create_users 之前的状态,users 表被删除,schema_migrations 表记录被删除
example=# select * from schema_migrations ; version | dirty---------+-------(0 rows)
3.2.5 应用多次修改
为了测试 migrations up [N] 执行多次修改的情形,第二次修改我们使用事务为 users 表增加 COLUMN,
migrate create -ext sql -dir ./migrations -seq add_mood_to_users , migrations 目录下会增加000002_add_mood_to_users.up.sql 和000002_add_mood_to_users.down.sql 两个文件。
000002_add_mood_to_users.up.sql :
BEGIN;CREATE TYPE enum_mood AS ENUM ( 'happy', 'sad', 'neutral');ALTER TABLE users ADD COLUMN IF NOT EXISTS mood enum_mood;COMMIT;
000002_add_mood_to_users.down.sql :
BEGIN;ALTER TABLE users DROP COLUMN IF EXISTS mood;DROP TYPE enum_mood;COMMIT;
第三次修改为 users 表增加 role_id 这个 COLUMN
migrate create -ext sql -dir ./migrations -seq add_roleid_to_users , migrations 目录下会增加000003_add_roleid_to_users.up.sql 和000003_add_roleid_to_users.down.sql 两个文件。
000003_add_roleid_to_users.up.sql
ALTER TABLE users ADD COLUMN IF NOT EXISTS role_id INTEGER;
000003_add_roleid_to_users.down.sql
ALTER TABLE users DROP COLUMN IF EXISTS role_id;
这样 migrations 目录下有如下6个 sql 文件:
.└── migrations ├── 000001_create_users_table.down.sql ├── 000001_create_users_table.up.sql ├── 000002_add_mood_to_users.down.sql ├── 000002_add_mood_to_users.up.sql ├── 000003_add_roleid_to_users.down.sql └── 000003_add_roleid_to_users.up.sql
3.2.5.1 应用多次修改
执行 migrate down 回滚 migrations 目录中所有修改。migrate -database 'postgres://postgres:mysecretpassword@192.168.10.212:5432/example?sslmode=disable' -path ./migrations down
migrate up 表示执行 migrations 目录中所有 up.sql 脚本。migrate -database 'postgres://postgres:mysecretpassword@192.168.10.212:5432/example?sslmode=disable' -path ./migrations up
migrate up [N], 表示从 schema_migrations 表的 version 的值后再执行 N 个部署。假设 schema_migration 中 version=1,migrate up [2] 就会执行 migrations 目录中 000001* 之后的000002_add_mood_to_users.up.sql 和000003_add_roleid_to_users.up.sql 两个操作。
3.2.6 测试执行失败的情况
首先执行 migrate down 回滚所有操作,然后执行 migrate up 2 应用000001_create_users_table.up.sql 和000002_add_mood_to_users.up.sql 。接下来我们修改000003_add_roleid_to_users.up.sql ,使得000003_add_roleid_to_users.up.sql 语法错误
这个时候查询 postgres 数据库的 schema_migrations 表,version=3,说明当前执行到 000003, 但是 dirty=t 说明执行有错误。
example=# select * from schema_migrations ; version | dirty---------+------- 3 | t(1 row)
然后修正000003_add_roleid_to_users.up.sql 的语法错误(去掉多余的 “errtest”),再次执行 migrate up 1,这个时候还是提示错误,因为 version=3 的 dirty=t,这个时候需要使用 migrate force 3 来确认说 version=3 的错误问题已修复,而且需要执行 migrate down 1 将 version 回退到 version=2 ,才能继续执行。
postgres migrate -database 'postgres://postgres:mysecretpassword@192.168.10.212:5432/example?sslmode=disable' -path ./migrations up 1error: migration failed: syntax error at or near "errtest" (column 60) in line 1: ALTER TABLE users ADD COLUMN IF NOT EXISTS role_id INTEGER errtest; (details: pq: syntax error at or near "errtest")➜ postgres migrate -database 'postgres://postgres:mysecretpassword@192.168.10.212:5432/example?sslmode=disable' -path ./migrations force 3➜ postgres migrate -database 'postgres://postgres:mysecretpassword@192.168.10.212:5432/example?sslmode=disable' -path ./migrations down 13/d add_roleid_to_users (34.332954ms)➜ postgres migrate -database 'postgres://postgres:mysecretpassword@192.168.10.212:5432/example?sslmode=disable' -path ./migrations up 13/u add_roleid_to_users (36.832839ms)
3.3 mysql 测试
说回前面说的测试 mysql 出现错误的问题,错误提示如下:
migrate -database mysql://root:x*xxx@192.168.10.212:3306/temp -path ./migrations upzsh: no matches found: mysql://root:x*xxx@192.168.10.212:3306/temp
查了一下这个错误是因为我使用的 shell 是 zsh, zsh 会自动解释 * ?等字符,而不是把 * ?留给命令 migrate 来解析,导致了错误,解决方案是在 ~/.zshrc 中加入:setopt no_nomatch 。另外一个解决方法是把 -database 参数的值加上引号 migrate -database 'mysql://root:x*xxx@192.168.10.212:3306/temp' -path ./migrations up
修正了 zsh 的问题后,再次执行 migrate up,还是提示错误:
migrate -database mysql://root:x*xxx@192.168.10.212:3306/temp -path ./migrations uperror: default addr for network '192.168.10.212:3306' unknown
这次的错误是因为 mysql 的 url 书写格式问题,mysql 的 url 需要写成 mysql://root:passwd@tcp(192.168.10.212:3306)/database 这样的格式。
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。