继第一篇,第二篇介绍了关于元数据的一些想法,最近做了一些改进。
对于一部分的元数据抽取大体有下面的两种方式。假设数据源已经做了很大的努力,终于统一起来了。我们现在要通过ssh的方式从源端抽取出数据来。
一种方式就是直接通过ssh的方式发送对应的查询脚本,然后可以得到一个完整的列表,二次加工即可。
另外一种方式是直接在每台服务器上都部署一个类似agent的载体,每个服务器端都会独立的运行这些脚本内容,然后通过ssh的方式返回即可。
当然下面的图有一些夸张,实际上没有这么多的数据源,只是说明了这种方式。
从个人的角度而言,如果喜欢偷懒类似一劳永逸的方式,我还是喜欢第一种方式,通过ssh发送脚本,然后返回服务端的运行结果。这种方式不需要特别的配置,比较轻巧快捷,当然这种场景的前提是脚本内容不大,调用次数不频繁。
假设调用的脚本为seal.sql,尝试使用下面的方式来调用。语句这么简答,我都有一种胜利在握的感觉了。
cat seal.sql | ssh 10.12.xxxx 'mysql '
但是奇怪的是,没有任何的输出。
反复尝试,在数据库端反复运行了脚本,内容都没有任何的问题。
所以感觉是不是这种方式会有一些特殊字符的影响或者是语句的注释干扰等等。
然后在得不到任何反馈的情况下,先尝试使用本地的方式来运行,远程调用脚本的形式,这种方式奇怪的是也依旧没有任何结果。
尝试了很多种方式,看起来是运行了,但是没有结果输出
# ssh 10.127.33.7 ' cat /home/dba/Monitor_Hardware/seal.sql|mysql '
Logging to file '/home/mysql/query.log'
# ssh 10.127.33.7 'mysql < /home/dba/Monitor_Hardware/seal.sql'
Logging to file '/home/mysql/query.log'
# ssh 10.127.33.7 'mysql < /home/dba/Monitor_Hardware/seal.sql > /tmp/a.log'
# ssh 10.127.33.7 "mysql < /home/dba/Monitor_Hardware/seal.sql > /tmp/a.log"
# ssh 10.127.33.7 "/usr/bin/mysql < /home/dba/Monitor_Hardware/seal.sql > /tmp/a.log"
# ssh 10.127.33.7 "/usr/bin/mysql < /home/dba/Monitor_Hardware/seal.sql > /tmp/a.log" # ssh 10.127.33.7 "mysql seal 'select user from mysql.user'"
Logging to file '/home/mysql/query.log'
调用了一个sql语句来验证,发现还是有结果输出的。
# ssh 10.127.33.7 "mysql seal -e 'select user from mysql.user'"
Logging to file '/home/mysql/query.log'
xxxxuser
sys_pm
mysqlmon
..
那么问题在哪里呢?
在反复查看脚本之后,唯一可以假定的就是里面有一个字段值是中文了。
sql语句类似 select xxxxx join xxxxx where device.server_responser in ('杨建荣');
按照这种情况来看,还是来看看是不是中文的影响。
可以使用这种方式来简单验证,传入变量LANG
cat seal.sql | ssh 10.127.33.7 'export LANG=en_US.utf-8;mysql -vv'
还是原来的脚本,加入-vv的选项,这种方式的输出结果为:
Empty set
Bye
看来就是语句运行了,但是因为字符集的不兼容,导致没有查询到任何结果。
这个问题的一个原因就是因为sql语句中的字段值为中文,可以尝试通过其它的code值来代替。
另外一个就是需要考虑字符集的情况,当然明确了这点。这个问题客户端为GBK,数据库端为UTF8,所以还是需要考虑这种差异,最后还是使用发送脚本的方式来运行,使用下面的方式来改进即可。
cat seal.sql |iconv -f GBK -t UTF8 | ssh 10.127.33.7 'export LANG=en_US.utf-8;mysql ' |iconv -f UTF8 -t GBK
对于一部分的元数据抽取大体有下面的两种方式。假设数据源已经做了很大的努力,终于统一起来了。我们现在要通过ssh的方式从源端抽取出数据来。
一种方式就是直接通过ssh的方式发送对应的查询脚本,然后可以得到一个完整的列表,二次加工即可。
另外一种方式是直接在每台服务器上都部署一个类似agent的载体,每个服务器端都会独立的运行这些脚本内容,然后通过ssh的方式返回即可。
当然下面的图有一些夸张,实际上没有这么多的数据源,只是说明了这种方式。
从个人的角度而言,如果喜欢偷懒类似一劳永逸的方式,我还是喜欢第一种方式,通过ssh发送脚本,然后返回服务端的运行结果。这种方式不需要特别的配置,比较轻巧快捷,当然这种场景的前提是脚本内容不大,调用次数不频繁。
假设调用的脚本为seal.sql,尝试使用下面的方式来调用。语句这么简答,我都有一种胜利在握的感觉了。
cat seal.sql | ssh 10.12.xxxx 'mysql '
但是奇怪的是,没有任何的输出。
反复尝试,在数据库端反复运行了脚本,内容都没有任何的问题。
所以感觉是不是这种方式会有一些特殊字符的影响或者是语句的注释干扰等等。
然后在得不到任何反馈的情况下,先尝试使用本地的方式来运行,远程调用脚本的形式,这种方式奇怪的是也依旧没有任何结果。
尝试了很多种方式,看起来是运行了,但是没有结果输出
# ssh 10.127.33.7 ' cat /home/dba/Monitor_Hardware/seal.sql|mysql '
Logging to file '/home/mysql/query.log'
# ssh 10.127.33.7 'mysql < /home/dba/Monitor_Hardware/seal.sql'
Logging to file '/home/mysql/query.log'
# ssh 10.127.33.7 'mysql < /home/dba/Monitor_Hardware/seal.sql > /tmp/a.log'
# ssh 10.127.33.7 "mysql < /home/dba/Monitor_Hardware/seal.sql > /tmp/a.log"
# ssh 10.127.33.7 "/usr/bin/mysql < /home/dba/Monitor_Hardware/seal.sql > /tmp/a.log"
# ssh 10.127.33.7 "/usr/bin/mysql < /home/dba/Monitor_Hardware/seal.sql > /tmp/a.log" # ssh 10.127.33.7 "mysql seal 'select user from mysql.user'"
Logging to file '/home/mysql/query.log'
调用了一个sql语句来验证,发现还是有结果输出的。
# ssh 10.127.33.7 "mysql seal -e 'select user from mysql.user'"
Logging to file '/home/mysql/query.log'
xxxxuser
sys_pm
mysqlmon
..
那么问题在哪里呢?
在反复查看脚本之后,唯一可以假定的就是里面有一个字段值是中文了。
sql语句类似 select xxxxx join xxxxx where device.server_responser in ('杨建荣');
按照这种情况来看,还是来看看是不是中文的影响。
可以使用这种方式来简单验证,传入变量LANG
cat seal.sql | ssh 10.127.33.7 'export LANG=en_US.utf-8;mysql -vv'
还是原来的脚本,加入-vv的选项,这种方式的输出结果为:
Empty set
Bye
看来就是语句运行了,但是因为字符集的不兼容,导致没有查询到任何结果。
这个问题的一个原因就是因为sql语句中的字段值为中文,可以尝试通过其它的code值来代替。
另外一个就是需要考虑字符集的情况,当然明确了这点。这个问题客户端为GBK,数据库端为UTF8,所以还是需要考虑这种差异,最后还是使用发送脚本的方式来运行,使用下面的方式来改进即可。
cat seal.sql |iconv -f GBK -t UTF8 | ssh 10.127.33.7 'export LANG=en_US.utf-8;mysql ' |iconv -f UTF8 -t GBK