feat: add query observability and collation safeguards
This commit is contained in:
@@ -298,6 +298,38 @@ REMOTE
|
||||
)" || fail "remote schema check failed: $remote_ssh:$remote_db"
|
||||
|
||||
[[ -z "$missing" ]] || fail "remote schema missing required tables: $(printf '%s' "$missing" | tr '\n' ', ' | sed 's/, $//')"
|
||||
local missing_query_trace_columns
|
||||
missing_query_trace_columns="$(ssh -o BatchMode=yes -o ConnectTimeout=10 "$remote_ssh" bash -s -- "$remote_db" <<'REMOTE'
|
||||
set -euo pipefail
|
||||
db="$1"
|
||||
mysql --batch --skip-column-names --connect-timeout=5 "$db" <<'SQL'
|
||||
SELECT required.column_name
|
||||
FROM (
|
||||
SELECT 'normalized_query_hash' AS column_name
|
||||
UNION ALL SELECT 'intent'
|
||||
UNION ALL SELECT 'domain'
|
||||
UNION ALL SELECT 'needs_clarification'
|
||||
UNION ALL SELECT 'outcome'
|
||||
UNION ALL SELECT 'outcome_reason'
|
||||
UNION ALL SELECT 'candidate_count'
|
||||
UNION ALL SELECT 'evidence_count'
|
||||
UNION ALL SELECT 'citation_count'
|
||||
UNION ALL SELECT 'rerank_applied'
|
||||
UNION ALL SELECT 'answer_hash'
|
||||
UNION ALL SELECT 'answer_length'
|
||||
UNION ALL SELECT 'update_time'
|
||||
) required
|
||||
LEFT JOIN information_schema.columns actual
|
||||
ON actual.table_schema = DATABASE()
|
||||
AND actual.table_name = 'aihr_knowledge_query_log'
|
||||
AND actual.column_name = required.column_name
|
||||
WHERE actual.column_name IS NULL
|
||||
ORDER BY required.column_name;
|
||||
SQL
|
||||
REMOTE
|
||||
)" || fail "remote query-trace schema check failed: $remote_ssh:$remote_db"
|
||||
[[ -z "$missing_query_trace_columns" ]] \
|
||||
|| fail "remote query-trace schema missing required columns: $(printf '%s' "$missing_query_trace_columns" | tr '\n' ', ' | sed 's/, $//')"
|
||||
local personal_oss_config
|
||||
personal_oss_config="$(ssh -o BatchMode=yes -o ConnectTimeout=10 "$remote_ssh" bash -s -- "$remote_db" <<'REMOTE'
|
||||
set -euo pipefail
|
||||
@@ -949,7 +981,26 @@ REMOTE
|
||||
|
||||
[[ "$media_reprocess_contract" = "source_attach_id|tenant_id,source_attach_id,id" ]] \
|
||||
|| fail "remote media-reprocess schema is invalid: got ${media_reprocess_contract:-missing}"
|
||||
|
||||
local aihr_collation_contract
|
||||
aihr_collation_contract="$(ssh -o BatchMode=yes -o ConnectTimeout=10 "$remote_ssh" bash -s -- "$remote_db" <<'REMOTE'
|
||||
set -euo pipefail
|
||||
db="$1"
|
||||
mysql --batch --skip-column-names --connect-timeout=5 "$db" <<'SQL'
|
||||
SELECT COUNT(*)
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name LIKE 'aihr\\_%' ESCAPE '\\'
|
||||
AND character_set_name IS NOT NULL
|
||||
AND (character_set_name <> 'utf8mb4' OR collation_name <> 'utf8mb4_0900_ai_ci');
|
||||
SQL
|
||||
REMOTE
|
||||
)" || fail "remote AIHR collation check failed: $remote_ssh:$remote_db"
|
||||
|
||||
[[ "$aihr_collation_contract" = "0" ]] \
|
||||
|| fail "remote AIHR tables still contain $aihr_collation_contract non-canonical character columns; apply aihr_20260804_unify_all_collations_mysql8.sql"
|
||||
echo "remote_schema=83/83 $remote_ssh:$remote_db"
|
||||
echo "remote_aihr_collation=0/0 $remote_ssh:$remote_db"
|
||||
echo "remote_rag_candidate_trace=1/1 $remote_ssh:$remote_db"
|
||||
echo "remote_media_reprocess_contract=1/1 $remote_ssh:$remote_db"
|
||||
echo "remote_work_report_idempotency=3/3 $remote_ssh:$remote_db"
|
||||
|
||||
@@ -26,6 +26,8 @@ docker exec -i wygj-mysql mysql -uroot -proot --default-character-set=utf8mb4 ry
|
||||
docker exec -i wygj-mysql mysql -uroot -proot --default-character-set=utf8mb4 ry-vue < "$ROOT_DIR/backend/script/sql/update/aihr_20260802_data_quality_observability_mysql8.sql"
|
||||
docker exec -i wygj-mysql mysql -uroot -proot --default-character-set=utf8mb4 ry-vue < "$ROOT_DIR/backend/script/sql/update/aihr_20260803_data_quality_structure_mysql8.sql"
|
||||
docker exec -i wygj-mysql mysql -uroot -proot --default-character-set=utf8mb4 ry-vue < "$ROOT_DIR/backend/script/sql/update/aihr_20260804_data_quality_feedback_loop_mysql8.sql"
|
||||
docker exec -i wygj-mysql mysql -uroot -proot --default-character-set=utf8mb4 ry-vue < "$ROOT_DIR/backend/script/sql/update/aihr_20260804_unify_all_collations_mysql8.sql"
|
||||
docker exec -i wygj-mysql mysql -uroot -proot --default-character-set=utf8mb4 ry-vue < "$ROOT_DIR/backend/script/sql/update/aihr_20260804_query_result_observability_mysql8.sql"
|
||||
docker exec -i wygj-mysql mysql -uroot -proot --default-character-set=utf8mb4 ry-vue < "$ROOT_DIR/backend/script/sql/update/aihr_20260805_knowledge_attachment_immutability_mysql8.sql"
|
||||
docker exec -i wygj-mysql mysql -uroot -proot --default-character-set=utf8mb4 ry-vue < "$ROOT_DIR/backend/script/sql/update/aihr_20260806_data_quality_extraction_evidence_mysql8.sql"
|
||||
docker exec -i wygj-mysql mysql -uroot -proot --default-character-set=utf8mb4 ry-vue < "$ROOT_DIR/backend/script/sql/update/aihr_20260807_data_quality_semantic_conflict_mysql8.sql"
|
||||
|
||||
@@ -22,6 +22,9 @@ trap cleanup EXIT
|
||||
mysql -e "CREATE DATABASE \`$DB\` CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;"
|
||||
mysql "$DB" <<'SQL'
|
||||
CREATE TABLE aihr_knowledge_info (tenant_id varchar(20) COLLATE utf8mb4_general_ci) ENGINE=InnoDB;
|
||||
CREATE TABLE aihr_knowledge_fragment (tenant_id varchar(20) COLLATE utf8mb4_general_ci, content text COLLATE utf8mb4_general_ci) ENGINE=InnoDB;
|
||||
CREATE TABLE aihr_data_asset (tenant_id varchar(20) COLLATE utf8mb4_0900_ai_ci, source_name varchar(100) COLLATE utf8mb4_0900_ai_ci) ENGINE=InnoDB;
|
||||
CREATE TABLE aihr_chunk_revision (tenant_id varchar(20) COLLATE utf8mb4_0900_ai_ci, content text COLLATE utf8mb4_0900_ai_ci) ENGINE=InnoDB;
|
||||
CREATE TABLE aihr_knowledge_space_grant (tenant_id varchar(20), label varchar(20)) ENGINE=InnoDB;
|
||||
CREATE TABLE aihr_knowledge_app (tenant_id varchar(20), label varchar(20)) ENGINE=InnoDB;
|
||||
CREATE TABLE aihr_knowledge_app_space (tenant_id varchar(20), label varchar(20)) ENGINE=InnoDB;
|
||||
@@ -56,4 +59,31 @@ aligned_columns="$(mysql "$DB" -N -B -e "
|
||||
")"
|
||||
test "$aligned_columns" = '38'
|
||||
|
||||
echo "PASS: AIHR release tables inherit the target database collation and the migration is idempotent"
|
||||
mysql "$DB" < "$ROOT_DIR/backend/script/sql/update/aihr_20260804_unify_all_collations_mysql8.sql"
|
||||
mysql "$DB" < "$ROOT_DIR/backend/script/sql/update/aihr_20260804_unify_all_collations_mysql8.sql"
|
||||
|
||||
noncanonical_columns="$(mysql "$DB" -N -B -e "
|
||||
SELECT COUNT(*)
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema='$DB'
|
||||
AND table_name LIKE 'aihr\\_%' ESCAPE '\\\\'
|
||||
AND character_set_name IS NOT NULL
|
||||
AND (character_set_name <> 'utf8mb4' OR collation_name <> 'utf8mb4_0900_ai_ci');
|
||||
")"
|
||||
test "$noncanonical_columns" = '0'
|
||||
|
||||
mysql "$DB" <<'SQL'
|
||||
INSERT INTO aihr_knowledge_info VALUES ('000000');
|
||||
INSERT INTO aihr_knowledge_fragment VALUES ('000000', '片段');
|
||||
INSERT INTO aihr_data_asset VALUES ('000000', '制度');
|
||||
INSERT INTO aihr_chunk_revision VALUES ('000000', '片段');
|
||||
SQL
|
||||
|
||||
join_count="$(mysql "$DB" -N -B -e "
|
||||
SELECT COUNT(*) FROM aihr_data_asset a
|
||||
JOIN aihr_chunk_revision c ON c.tenant_id = a.tenant_id
|
||||
JOIN aihr_knowledge_fragment f ON f.tenant_id = c.tenant_id;
|
||||
" "$DB")"
|
||||
test "$join_count" = '1'
|
||||
|
||||
echo "PASS: AIHR release tables inherit the target database collation and all-AIHR normalization is idempotent"
|
||||
|
||||
Reference in New Issue
Block a user