当前位置: 首页 > news >正文

ansible 实现达梦7数据库初始化数据脚本写入

关于使用ansible 对ARM版达梦7的k8s自动化部署参考我的这篇操作

ansible-playbook 写arm版达梦7数据库的一键安装脚本-CSDN博客文章浏览阅读303次,点赞5次,收藏3次。达梦官方提供镜像目前是dm8_x86 版本,因为众所周知的国产化方面的需求,需要在kylin v10机器上部署一个DM数据库以及其他使用数据库的服务,为了更便捷的交付需要把安装步骤都写入到ansible 脚本里,这里就单说下DM 的部署。 https://blog.csdn.net/u011564831/article/details/146979512?spm=1011.2415.3001.5331

下面进入另一个需要解决的问题,如何使用ansbile  实现达梦7数据库初始化数据脚本写入

对于有特定性数据配置的项目会需要在服务安装时候把db_init的初始文件, 根据实际部署的情况修改初始化数据的信息,等待准备好以后直接导入到数据库里,类似于mysql

mysql -u username -p your_database_name < /path/to/your/file.sql

sql数据渲染

因为我本地DM数据库是整个/dm7/data 搬家,所以表结构是不需要重新去创建,只要把一些业务表TRUNCATE 掉就可以, 然后把dm数据库需要动态插入数据的记录动态生成好等待导入

在任务里添加一个 Init DM 的节点

    # dm 数据库初始化
    - name: Init DM
      include_role:
        name: deploy_rlstudio
        tasks_from: 11.dm_init.yml
      when: (deploy_type is not defined) or (deploy_type == "dm_init")
      tags: [ "always" ]

在task_from 的文件里先从template  sql.jq 为底本生成要导入的 target.sql

---
- name: Render ConfigMap with namespace
  ansible.builtin.template:
    src: "{{ role_path }}/files/sql.jq2"
    dest: "{{ role_path }}/files/target.sql"
    mode: '0644'
  delegate_to: "{{ inventory_hostname }}"
  run_once: true
  vars:
    ansible_python_interpreter: "{{ custom_python_interpreter }}"

这样可以把已经全局定义的变量写入到target.sql里

比如sql.jq2了定义的,全局inventory下定义 了该变量rl_mysql_node: 10.10.121.12

INSERT INTO USER_QUOTAS_MANAGE.properties VALUES ('argoAddress', 'String', 'http://{{rl_mysql_node}}:30128');

在最后生成的target.sql里就可以动态写入上

还可以把要truncate的表名在Ansible Playbook 中先定义上

vars: arr: ["x1", "x2"]

  • sql.jq2 模板文件中使用 Jinja2 语法
    使用上述示例中的代码来遍历 arr 变量并生成 SQL 语句。当运行 Ansible Playbook 时,模板将被渲染,target.sql 文件将包含根据 arr 生成的 SQL 语句。

-- 清理原来的表数据
{% for item in arr %}
TRUNCATE TABLE USER_QUOTAS_MANAGE.{{ item }};
{% endfor %}

DM 数据库查看 表xx10 外键关联的方法

SELECT
    a.table_name AS referencing_table,
    a.constraint_name AS foreign_key_name
FROM
    user_constraints a
JOIN
    user_cons_columns b ON a.constraint_name = b.constraint_name
WHERE
    a.constraint_type = 'R'
    AND a.r_constraint_name IN (
        SELECT constraint_name
        FROM user_constraints
        WHERE table_name = 'xx10'  -- 替换为你的表名

然后是初始化表数据道理也差不多,把动态写入的变量在playbook先定义好然后执行

寻找一个类似mysql的sql文件导入方式

现在我已经有了待执行的sql文件,我的思路就是把这个文件复制到dm的 pod里然后用dm自带的disql 工具把文件导入进去

先把target.sql复制到pod里去

- name: Get DM7 Pod name using kubectl
  ansible.builtin.command:
    cmd: "kubectl get pods -n {{ dm7_namespace }} -l app=apps.deployment-dm-dm7 -o jsonpath='{.items[0].metadata.name}'"
  register: dm7_pod_name
  delegate_to: "{{ inventory_hostname }}"
  run_once: true
  vars:
    ansible_python_interpreter: "{{ custom_python_interpreter }}"

- name: Fail if no DM7 Pod is found
  ansible.builtin.fail:
    msg: "No DM7 Pod found in namespace {{ dm7_namespace }} with label app=apps.deployment-dm-dm7"
  when: dm7_pod_name.stdout == ""
  delegate_to: "{{ inventory_hostname }}"
  run_once: true
  vars:
    ansible_python_interpreter: "{{ custom_python_interpreter }}"

- name: Copy SQL file to DM7 Pod using kubectl cp
  ansible.builtin.command:
    cmd: "kubectl cp {{ role_path }}/files/target.sql {{ dm7_namespace }}/{{ dm7_pod_name.stdout }}:/dm7/data/target.sql"
  delegate_to: "{{ inventory_hostname }}"
  run_once: true
  when: dm7_pod_name.stdout != ""
  vars:
    ansible_python_interpreter: "{{ custom_python_interpreter }}"

然后调用 ./disql <user>/<password>@localhost:5236 -i /dm7/data/target.sql 做导入

- name: Execute target.sql in DM7 Pod
  ansible.builtin.command:
    cmd: >
      kubectl exec -n {{ dm7_namespace }} {{ dm7_pod_name.stdout }} -- 
      cd /dm7/bin && ./disql SYSDBA/123456789012@localhost:5236 -i /dm7/data/target.sql
  delegate_to: "{{ inventory_hostname }}"
  run_once: true
  when: dm7_pod_name.stdout != ""
  vars:
    ansible_python_interpreter: "{{ custom_python_interpreter }}"

先是报错 无法找到动态链接库 libdmdpi.so

TASK [deploy_rlstudio : Get DM7 Pod name] ************************************************************************************************** fatal: [192.168.107.9]: FAILED! => {"changed": false, "msg": "Failed to find executable libdmdpi.so"}

这个错在cmd里加上 export LD_LIBRARY_PATH=/dm7/bin:$LD_LIBRARY_PATH

- name: Execute target.sql in DM7 Pod
  ansible.builtin.command:
    cmd: >
      kubectl exec -n {{ dm7_namespace }} {{ dm7_pod_name.stdout }} -- 
      export LD_LIBRARY_PATH=/dm7/bin:$LD_LIBRARY_PATH && cd /dm7/bin && ./disql SYSDBA/123456789012@localhost:5236 -i /dm7/data/target.sql
  delegate_to: "{{ inventory_hostname }}"
  run_once: true
  when: dm7_pod_name.stdout != ""
  vars:
    ansible_python_interpreter: "{{ custom_python_interpreter }}"

执行结束ansible 没报错但是数据并没有导入成功

手动进入pod调试了下发现报错了

[root@dm7-7db84c6d-h9dgm /]# /dm7/bin/disql SYSDBA/123456789012@localhost:5236 -i /dm7/data/target.sql
 USAGE:CONN[ECT] <logon>

 <logon> : {<username>[/<password>][*<MPP_TYPE>][@<connect_identifier>]} | {/ AS <SYSDBA|SYSSSO|SYSAUDITOR|AUTO>}
 <connect_identifier> :{[<server>][:<port>][?{UDP|TCP|IPC|RDMA}][#<sslpath>@<sslpwd>]}

 <server>: if ipv6 address,[] is needed. For example [fe80::1e6f:65ff:fed1:3724%6]
DISQL usage1:disql -h|help  show disql version and help message

DISQL usage2:disql [ [<option>] [{<logon> | /NOLOG}] [<start>] ]

 <option> : [-L] [-S]

  -L only try to login once
  -S set no show model, hidden disql flag

 <logon> : {<username>[/<password>][*<MPP_TYPE>][@<connect_identifier>]} | {/ AS <SYSDBA|SYSSSO|SYSAUDITOR|AUTO>}
 <connect_identifier> :{[<server>][:<port>][?{UDP|TCP|IPC|RDMA}][#<sslpath>@<sslpwd>]}

 <server>: if ipv6 address,[] is needed. For example [fe80::1e6f:65ff:fed1:3724%6]

 <start> : `<filename>[<parameter> ...]<direct sql> run disql bash

 /NOLOG option can run disql, while not connected to DM server

 <direct sql>:-e "<SQL statement>[;<SQL statement>]"

先检查 disql 版本和支持的选项

运行以下命令查看 disql 的帮助信息:

/dm7/bin/disql -h

  • 检查输出中是否提到 - arroAddress,如果是,可能是个文档错误(应为 -i),说明版本支持问题。
  • 如果没有 -i,说明你的 disql 版本不支持此选项。

结论是我使用的dm7 这个disql 工具没有-i 这个选项

不过这也不是什么大问题, 想办法把target.sql里sql拆成可执行的一条条记录逐条执行就可以了

换个思路

从 DM7 Pod 中读取 SQL 文件内容

- name: Read SQL file content from DM7 Pod
  ansible.builtin.command:
    cmd: "kubectl exec -n {{ dm7_namespace }} {{ dm7_pod_name.stdout }} -- cat {{ sql_file }}"
  register: sql_content
  delegate_to: "{{ inventory_hostname }}"
  run_once: true
  when: dm7_pod_name.stdout != ""
  vars:
    sql_file: "/dm7/data/target.sql"
    ansible_python_interpreter: "{{ custom_python_interpreter }}"
  • 执行 kubectl exec 命令,进入指定的 Kubernetes Pod,并读取 SQL 文件的内容。
  • 注册变量:将读取的内容保存到变量 sql_content 中。
  • 条件执行:只有当 dm7_pod_name.stdout 不为空时,才会执行这个任务。
  • 使用的变量
    • dm7_namespace:命名空间。
    • dm7_pod_name.stdout:Pod 名称。
    • sql_file:SQL 文件的路径。

在 DM7 Pod 中执行 SQL 语句

- name: Execute SQL statements in DM7 Pod
  ansible.builtin.command:
    cmd: >
      kubectl exec -n {{ dm7_namespace }} {{ dm7_pod_name.stdout }} -- 
      sh -c "{{ disql_base_cmd }} \"{{ item | trim }}\""
  loop: "{{ (sql_content.stdout | split(';')) | list }}"
  delegate_to: "{{ inventory_hostname }}"
  run_once: true
  when:
    - dm7_pod_name.stdout != ""
    - item | trim | length > 0
  register: disql_result
  changed_when: disql_result.rc == 0
  failed_when: disql_result.rc != 0
  vars:
    disql_base_cmd: "export LD_LIBRARY_PATH=/dm7/bin:$LD_LIBRARY_PATH && /dm7/bin/disql SYSDBA/123456789012@localhost:5236 -e"
    ansible_python_interpreter: "{{ custom_python_interpreter }}"
  • 从第一步读取的 SQL 内容中提取 SQL 语句,并逐一执行。
  • 循环:将 sql_content.stdout 按分号 (;) 分割成列表,遍历每个 SQL 语句。
  • 条件执行:只有当 Pod 名称不为空且 SQL 语句非空时才执行。
  • 注册结果:将每个执行的结果保存到 disql_result 中。
  • 成功与失败条件
    • changed_when:如果返回代码为 0,则标记为成功。
    • failed_when:如果返回代码不为 0,则标记为失败。
  • 执行命令:使用 disql 命令执行 SQL 语句。

调试执行结果

- name: Debug execution result
  ansible.builtin.debug:
    var: disql_result
  when: disql_result is defined
  vars:
    ansible_python_interpreter: "{{ custom_python_interpreter }}"
  • 输出 disql_result 的内容,以便查看 SQL 执行的结果。
  • 条件执行:只有当 disql_result 被定义时才会执行这个任务。

修改后全部脚本

---
- name: Render ConfigMap with namespace
  ansible.builtin.template:
    src: "{{ role_path }}/files/sql.jq"
    dest: "{{ role_path }}/files/target.sql"
    mode: '0644'
  delegate_to: "{{ inventory_hostname }}"
  run_once: true
  vars:
    ansible_python_interpreter: "{{ custom_python_interpreter }}"

- name: Get DM7 Pod name using kubectl
  ansible.builtin.command:
    cmd: "kubectl get pods -n {{ dm7_namespace }} -l app=apps.deployment-dm-dm7 -o jsonpath='{.items[0].metadata.name}'"
  register: dm7_pod_name
  delegate_to: "{{ inventory_hostname }}"
  run_once: true
  vars:
    ansible_python_interpreter: "{{ custom_python_interpreter }}"

- name: Fail if no DM7 Pod is found
  ansible.builtin.fail:
    msg: "No DM7 Pod found in namespace {{ dm7_namespace }} with label app=apps.deployment-dm-dm7"
  when: dm7_pod_name.stdout == ""
  delegate_to: "{{ inventory_hostname }}"
  run_once: true
  vars:
    ansible_python_interpreter: "{{ custom_python_interpreter }}"

- name: Copy SQL file to DM7 Pod using kubectl cp
  ansible.builtin.command:
    cmd: "kubectl cp {{ role_path }}/files/target.sql {{ dm7_namespace }}/{{ dm7_pod_name.stdout }}:/dm7/data/target.sql"
  delegate_to: "{{ inventory_hostname }}"
  run_once: true
  when: dm7_pod_name.stdout != ""
  vars:
    ansible_python_interpreter: "{{ custom_python_interpreter }}"

- name: Read SQL file content from DM7 Pod
  ansible.builtin.command:
    cmd: "kubectl exec -n {{ dm7_namespace }} {{ dm7_pod_name.stdout }} -- cat {{ sql_file }}"
  register: sql_content
  delegate_to: "{{ inventory_hostname }}"
  run_once: true
  when: dm7_pod_name.stdout != ""
  vars:
    sql_file: "/dm7/data/target.sql"
    ansible_python_interpreter: "{{ custom_python_interpreter }}"

- name: Execute SQL statements in DM7 Pod
  ansible.builtin.command:
    cmd: >
      kubectl exec -n {{ dm7_namespace }} {{ dm7_pod_name.stdout }} -- 
      sh -c "{{ disql_base_cmd }} \"{{ item | trim }}\""
  #loop: "{{ (sql_content.stdout | split(';')) | select('match', '^(GRANT|SET|DROP|CREATE|INSERT)') | reject('match', '^\\s*--') | list }}"
  loop: "{{ (sql_content.stdout | split(';')) | list }}"
  delegate_to: "{{ inventory_hostname }}"
  run_once: true
  when:
    - dm7_pod_name.stdout != ""
    - item | trim | length > 0
  register: disql_result
  changed_when: disql_result.rc == 0
  failed_when: disql_result.rc != 0
  vars:
    disql_base_cmd: "export LD_LIBRARY_PATH=/dm7/bin:$LD_LIBRARY_PATH && /dm7/bin/disql SYSDBA/123456789012@localhost:5236 -e"
    ansible_python_interpreter: "{{ custom_python_interpreter }}"

- name: Debug execution result
  ansible.builtin.debug:
    var: disql_result
  when: disql_result is defined
  vars:
    ansible_python_interpreter: "{{ custom_python_interpreter }}"

执行没有错误

输出debug信息

后面检查了初始化的数据都插入成功了

http://www.dtcms.com/a/122811.html

相关文章:

  • docker使用
  • 2025年项目管理工具TOP10:Gitee引领技术驱动新浪潮
  • 【 C# 使用 MiniExcel 库的典型场景】
  • 开源免费虚拟化平台PVE软件定义网络
  • BGP路由协议之对等体
  • Containerd介绍
  • C++中如何在一个字符串中的任何一个位置插入字符或者字符串--insert()函数实现
  • Python星球日记 - 第18天:小游戏开发(猜数字游戏)
  • 前端视频流技术深度解析
  • Python爬虫教程011:scrapy爬取当当网数据开启多条管道下载及下载多页数据
  • 香港服务器租用对分布式计算的作用
  • Vue3中父组件将一个ref定义的对象类型传递给子组件的解包机制
  • 用Python构建区块链健康数据管理系统——隐私与信任的新纪元
  • python——正则表达式
  • vue3中defineProps的使用说明
  • Python 实现的运筹优化系统数学建模详解(0-1规划背包问题)
  • PHP:从诞生到未来的Web开发利器
  • 数据结构和大数据处理及其加密算法
  • SMB 协议
  • uniApp 设置动态tabs(不是自定义tab哈)
  • 在执行生信分析的时候提示缺少一些R包的报错解决
  • WebForms ViewState
  • SnowNLP 使用大全
  • Scala Iterator(迭代器)
  • 算法进阶指南 袭击
  • 蓝桥杯 跑步计划(模拟日期)
  • JMeter从入门到荒废-常见问题汇总
  • go游戏后端开发30:弃牌逻辑与后续操作
  • vue3中左右布局两个个组件使用vuedraggable实现左向右拖动,右组件列表可上下拖动
  • rook-ceph xx/xxx objects misplaced (xx%)