Skip to content

Commit c7b3055

Browse files
committed
sr_alter 批量修改表/物化视图副本数
1 parent 66a8ee3 commit c7b3055

File tree

2 files changed

+214
-0
lines changed

2 files changed

+214
-0
lines changed
+102
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
"""
2+
starrocks 批量修改表副本数,可配置修改前和修改后的副本数。
3+
普通表及分区表。
4+
"""
5+
import pymysql
6+
import time
7+
8+
9+
# 副本数配置
10+
REPLICATION_NUM_BEFORE = "3" # 修改前的副本数
11+
REPLICATION_NUM_AFTER = "1" # 修改后的副本数
12+
13+
# 数据库连接配置
14+
DB_CONFIG = {
15+
"host": "127.0.0.1",
16+
"user": "root",
17+
"password": "root.COM2025*",
18+
"database": "information_schema",
19+
"port": 9030,
20+
}
21+
22+
23+
def fetch_tables_with_replication_num(connection):
24+
"""查询指定 replication_num 的普通表"""
25+
query = f"""
26+
SELECT TABLE_SCHEMA, TABLE_NAME
27+
FROM information_schema.tables_config
28+
WHERE TABLE_ENGINE='OLAP' AND PROPERTIES LIKE '%"replication_num":"{REPLICATION_NUM_BEFORE}"%'
29+
"""
30+
with connection.cursor() as cursor:
31+
cursor.execute(query)
32+
return cursor.fetchall()
33+
34+
35+
def fetch_partition_tables_with_replication_num(connection):
36+
"""查询指定 replication_num 的分区表"""
37+
query = f"""
38+
SELECT TABLE_SCHEMA, TABLE_NAME
39+
FROM information_schema.tables_config
40+
WHERE TABLE_ENGINE='OLAP' AND PARTITION_KEY <> '' AND PROPERTIES LIKE '%"replication_num":"{REPLICATION_NUM_BEFORE}"%'
41+
"""
42+
with connection.cursor() as cursor:
43+
cursor.execute(query)
44+
return cursor.fetchall()
45+
46+
47+
def alter_table_replication_num(connection, schema, table):
48+
"""修改普通表的 replication_num"""
49+
alter_sql = (
50+
f'ALTER TABLE `{schema}`.`{table}` SET ("default.replication_num" = "{REPLICATION_NUM_AFTER}")'
51+
)
52+
try:
53+
with connection.cursor() as cursor:
54+
cursor.execute(alter_sql)
55+
print(f"[INFO] Successfully altered table: {schema}.{table}")
56+
except Exception as e:
57+
print(f"[ERROR] Failed to alter table {schema}.{table}: {str(e)}")
58+
59+
60+
def alter_partition_replication_num(connection, schema, table):
61+
"""修改分区表的 replication_num"""
62+
alter_sql = f'ALTER TABLE `{schema}`.`{table}` MODIFY PARTITION (*) SET("replication_num"="{REPLICATION_NUM_AFTER}")'
63+
try:
64+
with connection.cursor() as cursor:
65+
cursor.execute(alter_sql)
66+
print(f"[INFO] Successfully altered partition table: {schema}.{table}")
67+
except Exception as e:
68+
print(f"[ERROR] Failed to alter partition table {schema}.{table}: {str(e)}")
69+
70+
71+
def main():
72+
# 连接数据库
73+
connection = pymysql.connect(**DB_CONFIG)
74+
try:
75+
# 获取需要修改的普通表
76+
tables = fetch_tables_with_replication_num(connection)
77+
if not tables:
78+
print(f"[INFO] No normal tables found with replication_num={REPLICATION_NUM_BEFORE}.")
79+
else:
80+
# 遍历并修改普通表
81+
for schema, table in tables:
82+
alter_table_replication_num(connection, schema, table)
83+
time.sleep(0.5)
84+
85+
# 获取需要修改的分区表
86+
partition_tables = fetch_partition_tables_with_replication_num(connection)
87+
if not partition_tables:
88+
print(f"[INFO] No partition tables found with replication_num={REPLICATION_NUM_BEFORE}.")
89+
else:
90+
# 遍历并修改分区表
91+
for schema, table in partition_tables:
92+
alter_partition_replication_num(connection, schema, table)
93+
time.sleep(0.5)
94+
95+
# 提交事务
96+
connection.commit()
97+
finally:
98+
connection.close()
99+
100+
101+
if __name__ == "__main__":
102+
main()
+112
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
"""
2+
starrocks 批量修改物化视图副本数,可配置修改前和修改后的副本数。(删除重建)
3+
SR (v3.2.15)当前物化视图无法修改副本数,已反馈官方:
4+
MySQL [information_schema]> ALTER MATERIALIZED VIEW dsj_dwd.mv_zt_hhy_staff_user_company_info SET ("replication_num" = "1");
5+
ERROR 1064 (HY000): Unexpected exception: Getting analyzing error. Detail message: Modify failed because unknown properties: {replication_num=1}, please add `session.` prefix if you want add session variables for mv(eg, "session.query_timeout"="30000000")..
6+
"""
7+
import pymysql
8+
import time
9+
10+
# 副本数配置
11+
REPLICATION_NUM_BEFORE = "3" # 修改前的副本数
12+
REPLICATION_NUM_AFTER = "1" # 修改后的副本数
13+
14+
# 数据库连接配置
15+
DB_CONFIG = {
16+
"host": "127.0.0.1",
17+
"user": "root",
18+
"password": "root.COM2025*",
19+
"database": "information_schema",
20+
"port": 9030,
21+
}
22+
23+
24+
def fetch_materialized_views():
25+
"""查询所有指定 replication_num 的物化视图"""
26+
query = f"""
27+
SELECT TABLE_SCHEMA, TABLE_NAME
28+
FROM information_schema.tables_config
29+
WHERE TABLE_ENGINE = 'MATERIALIZED_VIEW'
30+
AND PROPERTIES LIKE '%"replication_num":"{REPLICATION_NUM_BEFORE}"%';
31+
"""
32+
connection = pymysql.connect(**DB_CONFIG)
33+
try:
34+
with connection.cursor() as cursor:
35+
cursor.execute(query)
36+
return cursor.fetchall()
37+
finally:
38+
connection.close()
39+
40+
41+
def get_create_view_statement(schema, table):
42+
"""获取物化视图的创建语句"""
43+
query = f"SHOW CREATE TABLE `{schema}`.`{table}`;"
44+
connection = pymysql.connect(**DB_CONFIG)
45+
try:
46+
with connection.cursor() as cursor:
47+
cursor.execute(query)
48+
result = cursor.fetchone()
49+
return result[1] # 返回创建语句
50+
finally:
51+
connection.close()
52+
53+
54+
def drop_view(schema, table):
55+
"""删除物化视图"""
56+
query = f"DROP MATERIALIZED VIEW `{schema}`.`{table}`;"
57+
connection = pymysql.connect(**DB_CONFIG)
58+
try:
59+
with connection.cursor() as cursor:
60+
cursor.execute(query)
61+
connection.commit()
62+
finally:
63+
connection.close()
64+
65+
66+
def create_view(create_statement):
67+
"""创建物化视图"""
68+
print(create_statement)
69+
connection = pymysql.connect(**DB_CONFIG)
70+
try:
71+
with connection.cursor() as cursor:
72+
cursor.execute(create_statement)
73+
connection.commit()
74+
finally:
75+
connection.close()
76+
77+
78+
def update_replication_num(schema, create_statement):
79+
"""修改创建语句中的 replication_num"""
80+
return create_statement.replace(
81+
f'"replication_num" = "{REPLICATION_NUM_BEFORE}"',
82+
f'"replication_num" = "{REPLICATION_NUM_AFTER}"'
83+
).replace("CREATE MATERIALIZED VIEW ", f"CREATE MATERIALIZED VIEW `{schema}`.")
84+
85+
86+
def main():
87+
# 获取所有指定 replication_num 的物化视图
88+
views = fetch_materialized_views()
89+
for schema, table in views:
90+
print(f"Processing view: {schema}.{table}")
91+
92+
# 获取创建语句
93+
create_statement = get_create_view_statement(schema, table)
94+
print("Original create statement fetched.")
95+
96+
# 修改 replication_num
97+
updated_statement = update_replication_num(schema, create_statement)
98+
print(f"Create statement updated with replication_num={REPLICATION_NUM_AFTER}.")
99+
time.sleep(0.5)
100+
101+
# 删除原视图
102+
drop_view(schema, table)
103+
print(f"Original view dropped: {schema}.{table}")
104+
time.sleep(0.5)
105+
106+
# 重新创建视图
107+
create_view(updated_statement)
108+
print(f"View recreated with updated replication_num={REPLICATION_NUM_AFTER}.----------")
109+
110+
111+
if __name__ == "__main__":
112+
main()

0 commit comments

Comments
 (0)