我正在编写一个剧本,将从 Oracle 数据库中选择所有用户。我采用了本文中所示的方法。
这是整个剧本
---
- name: Gather all users details and save to JSON
hosts: all
become: yes
gather_facts: yes
tasks:
- block:
- name: query
shell: |
sqlplus / as sysdba
set pagesize 999;
set linesize 999;
select username from dba_users;
exit;
register: user_output
environment:
ORACLE_SID: "MYDB"
ORACLE_HOME: "myOracleHome"
PATH: "myOraclePATH"
LD_LIBRARY_PATH: "myLibPath"
- name: Print output
ansible.builtin.debug:
msg: out {{ user_output.stdout_lines }}
become: yes
become_user: oracle
我已经为这台特定机器设置了所有必要的环境变量(目前我仅在单个主机上进行测试)。
现在问题出在哪里?问题是,当 ansible 执行到 query 任务时,它会挂起,我不知道它会持续多久,因为当它达到 10 分钟时,我就放弃了等待。
我正在测试的机器有很多数据库并且非常大,但我在一个较小的数据库上运行查询,该数据库只有 46 个用户。
我已确保查询有效,在本地运行时只需不到一秒,因此问题不存在。
我还在调试模式下运行了这个剧本,添加了
-vvv
标志,看起来它完全挂在 query 任务上,它成功设置了环境变量,然后什么都不做!
有趣的事实,当我运行剧本没有设置环境变量时,它不会挂起,而是给出了预期的错误
sqlplus: command not found
,所以它实际上是在做某事。
这是查询任务的调试日志:
<x.x.x.x> ESTABLISH SSH CONNECTION FOR USER: myUser
<x.x.x.x> SSH: EXEC sshpass -d12 ssh -C -o ControlMaster=auto -o ControlPersist=60s -o 'User="myUser"' -o ConnectTimeout=10 -o 'ControlPath="/home/ansible/.ansible/cp/686fbcfc81"' x.x.x.x '/bin/sh -c '"'"'echo ~myUser && sleep 0'"'"''
<x.x.x.x> (0, b'/home/myUser\n', b'')
<x.x.x.x> ESTABLISH SSH CONNECTION FOR USER: myUser
<x.x.x.x> SSH: EXEC sshpass -d12 ssh -C -o ControlMaster=auto -o ControlPersist=60s -o 'User="myUser"' -o ConnectTimeout=10 -o 'ControlPath="/home/ansible/.ansible/cp/686fbcfc81"' x.x.x.x '/bin/sh -c '"'"'( umask 77 && mkdir -p "` echo /var/tmp `"&& mkdir "` echo /var/tmp/ansible-tmp-1726830229.8966174-18573-196770779260426 `" && echo ansible-tmp-1726830229.8966174-18573-196770779260426="` echo /var/tmp/ansible-tmp-1726830229.8966174-18573-196770779260426 `" ) && sleep 0'"'"''
<x.x.x.x> (0, b'ansible-tmp-1726830229.8966174-18573-196770779260426=/var/tmp/ansible-tmp-1726830229.8966174-18573-196770779260426\n', b'')
Using module file /usr/lib/python3.11/site-packages/ansible/modules/command.py
<x.x.x.x> PUT /home/ansible/.ansible/tmp/ansible-local-18525yaa_4d63/tmpw0g9yu2l TO /var/tmp/ansible-tmp-1726830229.8966174-18573-196770779260426/AnsiballZ_command.py
<x.x.x.x> SSH: EXEC sshpass -d12 sftp -o BatchMode=no -b - -C -o ControlMaster=auto -o ControlPersist=60s -o 'User="myUser"' -o ConnectTimeout=10 -o 'ControlPath="/home/ansible/.ansible/cp/686fbcfc81"' '[x.x.x.x]'
<x.x.x.x> (0, b'sftp> put /home/ansible/.ansible/tmp/ansible-local-18525yaa_4d63/tmpw0g9yu2l /var/tmp/ansible-tmp-1726830229.8966174-18573-196770779260426/AnsiballZ_command.py\n', b'')
<x.x.x.x> ESTABLISH SSH CONNECTION FOR USER: myUser
<x.x.x.x> SSH: EXEC sshpass -d12 ssh -C -o ControlMaster=auto -o ControlPersist=60s -o 'User="myUser"' -o ConnectTimeout=10 -o 'ControlPath="/home/ansible/.ansible/cp/686fbcfc81"' x.x.x.x '/bin/sh -c '"'"'setfacl -m u:oracle:r-x
/var/tmp/ansible-tmp-1726830229.8966174-18573-196770779260426/ /var/tmp/ansible-tmp-1726830229.8966174-18573-196770779260426/AnsiballZ_command.py && sleep 0'"'"''
<x.x.x.x> (0, b'', b'')
<x.x.x.x> ESTABLISH SSH CONNECTION FOR USER: myUser
<x.x.x.x> SSH: EXEC sshpass -d12 ssh -C -o ControlMaster=auto -o ControlPersist=60s -o 'User="myUser"' -o ConnectTimeout=10 -o 'ControlPath="/home/ansible/.ansible/cp/686fbcfc81"' -tt x.x.x.x '/bin/sh -c '"'"'sudo -H -S -n -u oracle
/bin/sh -c '"'"'"'"'"'"'"'"'echo BECOME-SUCCESS-tqqxhtcntukpuwtfraxcpodtkmmxahln ;
ORACLE_SID=MySID ORACLE_HOME=homePath PATH=myPath LD_LIBRARY_PATH=myLibPath /usr/bin/python3.6 /var/tmp/ansible-tmp-1726830229.8966174-18573-196770779260426/AnsiballZ_command.py'"'"'"'"'"'"'"'"' && sleep 0'"'"''
Escalation succeeded
出现升级成功消息后,它会挂起。 我已经没有办法解决这个问题了,任何其他不涉及数据库的 Ansible 任务都可以正常工作。
Oracle DB 完整版本信息:
Oracle Database 19c Standard Edition 2 Release 19.0.0.0.0 - Production
Version 19.23.0.0.0
您似乎正在运行
sqlplus
,并且 playbook 正在等待该操作完成,然后再运行 shell 中的下一行。它似乎没有将后续行传递到sqlplus
,以便命令永远运行,等待用户输入。
你可以尝试:
echo "set pagesize 999;
set linesize 999;
select username from dba_users;" | sqlplus / as sysdba