我一直在尝试整理来 self 的开发 CentOS 7 服务器和开发 mysql 8.0 数据库的信息,并将它们输入到一个单独的数据库/表中,以供监控仪表板读取。目前,我正在尝试检索 mysql 中每个数据库的所有表存储大小,并将数据输入到单独的表中。
我在使用 bash 变量保存数据库名称时遇到了问题。对于某些数据库名称,它工作得很好,但对于其他数据库名称,即使使用相同的语法,我也遇到了问题。
我一直在运行“TableStorage”函数来执行 insert into select 语句来填充我的 TABLE_STORAGE 监控表(见下文)
function TableStorage {
DB1='database1'
DB2='database2'
mysql -u $DBA_USER -p$DBA_PASS <<EOF
INSERT INTO splunk.TABLE_STORAGE (TABLE_SCHEMA, TABLE_NAME, SIZE_MB) SELECT TABLE_SCHEMA, TABLE_NAME, ROUND((DATA_LENGTH + INDEX_LENGTH) / 1024 / 1024)
FROM information_schema.TABLES WHERE TABLE_SCHEMA = '$DB1' ORDER BY (DATA_LENGTH + INDEX_LENGTH) DESC;
INSERT INTO splunk.TABLE_STORAGE (TABLE_SCHEMA, TABLE_NAME, SIZE_MB) SELECT TABLE_SCHEMA, TABLE_NAME, ROUND((DATA_LENGTH + INDEX_LENGTH) / 1024 / 1024)
FROM information_schema.TABLES WHERE TABLE_SCHEMA = '$DB2' ORDER BY (DATA_LENGTH + INDEX_LENGTH) DESC;
COMMIT;
EOF
}
但是,当我运行上述函数时,仅将“database1”中的表信息插入到“database1”和“database2”中,而不是同时插入“database1”和“database2”。 我可以确认两个数据库都有多个表,因此数据并不存在。 即使我只运行了使用函数插入“database2”中的表的插入语句,我仍然没有运气。 我还在 mysql 中手动运行了上述两条语句,并且所有表都是以这种方式插入的,只是在函数中运行时没有这样做。
我还仔细检查了以下内容: -db 存在 - 存在表格 -bash 变量已设置 -在 bash 中回显整个语句以确保变量正确填充插入语句(它们确实如此)
真的很难过这个问题,我可以想象这是一个我错过的非常愚蠢的错误。任何帮助,将不胜感激。
最佳答案
带有准备好的语句的示例:
#!/usr/bin/env bash
TableStorage() {
[ "$#" -ne 2 ] && return 1 # Two database-name arguments required
mysql -u "$DBA_USER" -p "$DBA_PASS" <<EOF
PREPARE stmt1 FROM 'INSERT INTO splunk.TABLE_STORAGE (TABLE_SCHEMA, TABLE_NAME, SIZE_MB) SELECT TABLE_SCHEMA, TABLE_NAME, ROUND((DATA_LENGTH + INDEX_LENGTH) / 1024 / 1024)
FROM information_schema.TABLES WHERE TABLE_SCHEMA = @db ORDER BY (DATA_LENGTH + INDEX_LENGTH) DESC';
SET @db="$1";
EXECUTE stmt1 USING @db;
SET @db="$2";
EXECUTE stmt1 USING @db;
COMMIT;
DEALLOCATE PREPARE stmt1;
EOF
}
if TableStorage 'database1' 'database2'; then
echo "TableStorage ok"
else
echo "Failure to run TableStorage" >&2
fi
或者使用任意数量的数据库名称:
#!/usr/bin/env bash
TableStorage() {
# Block to compose the SQL commands stream
{
# Prepare a statement
echo "PREPARE stmt1 FROM 'INSERT INTO splunk.TABLE_STORAGE (TABLE_SCHEMA, TABLE_NAME, SIZE_MB) SELECT TABLE_SCHEMA, TABLE_NAME, ROUND((DATA_LENGTH + INDEX_LENGTH) / 1024 / 1024) FROM information_schema.TABLES WHERE TABLE_SCHEMA = @db ORDER BY (DATA_LENGTH + INDEX_LENGTH) DESC';"
# While there is a database name argument
while [ "$#" -gt 0 ]; do
# Set SQL variable @db to database name argument $1
# and execute the prepared statement
printf 'SET @db="%s";\nEXECUTE stmt1 USING @db;\n' "$1"
# Shift to next argument $1
shift
done
# Commit the changes
echo "COMMIT;"
# Dispose of the prepared statement
echo "DEALLOCATE PREPARE stmt1;"
} |
# Pipe the SQL commands to MySQL
mysql -u "$DBA_USER" -p "$DBA_PASS"
}
if TableStorage 'database1' 'database2'; then
echo "TableStorage ok"
else
echo "Failure to run TableStorage" >&2
fi
关于mysql - 将 bash 变量应用于 mysql 插入语句 - 对某些人有效,但对其他人无效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59359723/