Files
inquiry_robot/deploy/_remote_mysql_skip_grant_create.ps1
T

196 lines
8.1 KiB
PowerShell
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 本机 YTD-MySQL:用 skip-grant-tables + skip-networking 短暂维护窗口,
# 重置 root、创建空库 inquiry_robot + 用户,然后恢复服务。
# 不打印口令。不碰 10.206.0.14 / jeecg-boot。
$ErrorActionPreference = "Stop"
$mysqlBin = "C:\yutongda\tools\mysql-8.0.39-winx64\bin"
$mysql = Join-Path $mysqlBin "mysql.exe"
$mysqld = Join-Path $mysqlBin "mysqld.exe"
$ini = "C:\yutongda\tools\mysql-8.0.39-winx64\my.ini"
$datadir = "C:\yutongda\data\mysql"
$ops = "E:\wwwroot\ops"
$secrets = Get-Content (Join-Path $ops "inquiry_robot_db_secrets.json") -Raw | ConvertFrom-Json
$psql = "C:\yutongda\tools\pgsql\bin\psql.exe"
function New-Secret([int]$len = 48) {
$bytes = New-Object byte[] $len
[System.Security.Cryptography.RandomNumberGenerator]::Create().GetBytes($bytes)
return ([Convert]::ToBase64String($bytes) -replace '[+/=]', 'x').Substring(0, [Math]::Min(64, $len))
}
function Test-AppMysql([string]$pass) {
$out = & $mysql -h127.0.0.1 -P3306 -uinquiry_robot "-p$pass" --connect-timeout=8 --batch -N inquiry_robot -e "SELECT 1" 2>&1
$text = ($out | ForEach-Object {"$_"}) -join "`n"
if ($text -match "ERROR\s+\d+") { return $false }
$lines = $out | ForEach-Object {"$_".Trim()} | Where-Object { $_ -ne "" -and $_ -notmatch "Warning" }
return ($lines -contains "1")
}
Write-Output "=== preflight: established on 3306? ==="
$est = @(Get-NetTCPConnection -LocalPort 3306 -State Established -EA SilentlyContinue)
Write-Output ("established=" + $est.Count)
if ($est.Count -gt 0) {
$est | Select-Object -First 5 | ForEach-Object {
"remote=$($_.RemoteAddress) pid=$($_.OwningProcess)"
}
throw "refuse skip-grant: active clients on local 3306"
}
# 生成/复用 root 新口令(仅存 ops,不进 Git)
$rootStash = Join-Path $ops "local_mysql_root_secret.json"
if (Test-Path $rootStash) {
$rootObj = Get-Content $rootStash -Raw | ConvertFrom-Json
$rootPass = [string]$rootObj.root_password
} else {
$rootPass = New-Secret 48
@{ root_password = $rootPass; createdAt = (Get-Date).ToString("o"); note = "local YTD-MySQL root on app server only" } |
ConvertTo-Json | Set-Content $rootStash -Encoding UTF8
}
$mysqlPass = [string]$secrets.mysql_password
if ([string]::IsNullOrWhiteSpace($mysqlPass)) { throw "missing secrets.mysql_password" }
Write-Output "=== stop YTD-MySQL service ==="
$svc = Get-Service YTD-MySQL -EA Stop
if ($svc.Status -ne "Stopped") {
Stop-Service YTD-MySQL -Force -ErrorAction Stop
}
# 确保进程退出
Start-Sleep -Seconds 2
Get-Process mysqld -EA SilentlyContinue | ForEach-Object {
Write-Output ("kill leftover mysqld pid=" + $_.Id)
Stop-Process -Id $_.Id -Force -EA SilentlyContinue
}
Start-Sleep -Seconds 2
if (Get-Process mysqld -EA SilentlyContinue) { throw "mysqld still running" }
Write-Output "STOPPED"
Write-Output "=== start mysqld skip-grant + skip-networking ==="
$errLog = Join-Path $ops "mysql-skip-grant.err"
if (Test-Path $errLog) { Remove-Item $errLog -Force }
$args = @(
"--defaults-file=$ini",
"--datadir=$datadir",
"--skip-grant-tables",
"--skip-networking",
"--shared-memory",
"--log-error=$errLog"
)
$p = Start-Process -FilePath $mysqld -ArgumentList $args -PassThru -WindowStyle Hidden
Write-Output ("maint_pid=" + $p.Id)
# 等可连(shared memory / named pipe,无 TCP)
$ready = $false
for ($i = 0; $i -lt 30; $i++) {
Start-Sleep -Seconds 1
if ($p.HasExited) {
Get-Content $errLog -Tail 20 -EA SilentlyContinue
throw "maint mysqld exited early code=$($p.ExitCode)"
}
$out = & $mysql -u root --batch -N -e "SELECT 1" 2>&1
$lines = $out | ForEach-Object {"$_".Trim()} | Where-Object { $_ -ne "" -and $_ -notmatch "Warning|ERROR" }
if ($lines -contains "1") { $ready = $true; break }
}
if (-not $ready) {
Get-Content $errLog -Tail 30 -EA SilentlyContinue
throw "maint mysqld not ready"
}
Write-Output "MAINT_READY"
Write-Output "=== flush privileges + reset root + create DB ==="
# skip-grant-tables 下需先 FLUSH PRIVILEGES 才能 ALTER USER
$sql = @"
FLUSH PRIVILEGES;
ALTER USER 'root'@'localhost' IDENTIFIED BY '$rootPass';
CREATE USER IF NOT EXISTS 'root'@'127.0.0.1' IDENTIFIED BY '$rootPass';
ALTER USER 'root'@'127.0.0.1' IDENTIFIED BY '$rootPass';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION;
GRANT ALL PRIVILEGES ON *.* TO 'root'@'127.0.0.1' WITH GRANT OPTION;
CREATE DATABASE IF NOT EXISTS ``inquiry_robot`` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER IF NOT EXISTS 'inquiry_robot'@'localhost' IDENTIFIED BY '$mysqlPass';
CREATE USER IF NOT EXISTS 'inquiry_robot'@'127.0.0.1' IDENTIFIED BY '$mysqlPass';
CREATE USER IF NOT EXISTS 'inquiry_robot'@'%' IDENTIFIED BY '$mysqlPass';
ALTER USER 'inquiry_robot'@'localhost' IDENTIFIED BY '$mysqlPass';
ALTER USER 'inquiry_robot'@'127.0.0.1' IDENTIFIED BY '$mysqlPass';
ALTER USER 'inquiry_robot'@'%' IDENTIFIED BY '$mysqlPass';
GRANT ALL PRIVILEGES ON ``inquiry_robot``.* TO 'inquiry_robot'@'localhost';
GRANT ALL PRIVILEGES ON ``inquiry_robot``.* TO 'inquiry_robot'@'127.0.0.1';
GRANT ALL PRIVILEGES ON ``inquiry_robot``.* TO 'inquiry_robot'@'%';
FLUSH PRIVILEGES;
SELECT 'maint_ok' AS s;
"@
$sqlPath = Join-Path $ops "sql\_maint_create_inquiry_robot.sql"
Set-Content $sqlPath -Value $sql -Encoding ascii
$mout = & $mysql -u root -e "source $($sqlPath -replace '\\','/')" 2>&1 | Out-String
$mout -split "`r?`n" | ForEach-Object {
if ($_ -match 'password|IDENTIFIED BY') { return }
$_
}
if ($mout -notmatch "maint_ok") { throw "maint SQL failed" }
Write-Output "SQL_OK"
Write-Output "=== stop maint mysqld ==="
Stop-Process -Id $p.Id -Force -EA SilentlyContinue
Start-Sleep -Seconds 2
# 若仍在,再杀
Get-Process -Id $p.Id -EA SilentlyContinue | Stop-Process -Force
Start-Sleep -Seconds 2
Get-Process mysqld -EA SilentlyContinue | Stop-Process -Force -EA SilentlyContinue
Start-Sleep -Seconds 2
if (Get-Process mysqld -EA SilentlyContinue) { throw "could not stop maint mysqld" }
Write-Output "=== start YTD-MySQL service ==="
Start-Service YTD-MySQL
$okSvc = $false
for ($i = 0; $i -lt 30; $i++) {
Start-Sleep -Seconds 1
$s = (Get-Service YTD-MySQL).Status
if ($s -eq "Running" -and (Test-AppMysql $mysqlPass)) { $okSvc = $true; break }
}
if (-not $okSvc) {
Write-Output ("service=" + (Get-Service YTD-MySQL).Status)
throw "service up but app smoke failed"
}
Write-Output "MYSQL_CREATED_OK"
# 清理含口令临时 SQL
Remove-Item $sqlPath -Force -EA SilentlyContinue
Set-Content (Join-Path $ops ".mysql_root_stash.tmp") -Value $rootPass -Encoding ascii -NoNewline
Write-Output "=== confirm PG + patch .env ==="
$env:PGPASSWORD = [string]$secrets.pg_password
$pgSmoke = & $psql -h 127.0.0.1 -p 5432 -U inquiry_robot_runtime -d inquiry_robot_runtime -tAc "SELECT 'pg_app_ok'" 2>&1
Write-Output ("PG=" + (($pgSmoke | ForEach-Object {"$_"}) -join " "))
if (($pgSmoke | Out-String) -notmatch "pg_app_ok") { throw "pg smoke failed" }
Remove-Item Env:PGPASSWORD -EA SilentlyContinue
$envPath = "E:\wwwroot\.env"
$lines = Get-Content $envPath
$out = foreach ($line in $lines) {
if ($line -match '^MYSQL_HOST=') { 'MYSQL_HOST=127.0.0.1' }
elseif ($line -match '^PG_HOST=') { 'PG_HOST=127.0.0.1' }
elseif ($line -match '^YTD_MYSQL_URL=') {
'YTD_MYSQL_URL=jdbc:mysql://127.0.0.1:3306/inquiry_robot?characterEncoding=UTF-8&useUnicode=true&useSSL=false&allowPublicKeyRetrieval=true&tinyInt1isBit=false&serverTimezone=Asia/Shanghai'
}
elseif ($line -match '^MYSQL_PASSWORD=') { "MYSQL_PASSWORD=$mysqlPass" }
elseif ($line -match '^PG_PASSWORD=') { "PG_PASSWORD=$($secrets.pg_password)" }
else { $line }
}
Set-Content $envPath -Value $out -Encoding UTF8
if (Test-Path "E:\wwwroot\agent\current") {
Copy-Item $envPath "E:\wwwroot\agent\current\.env" -Force
}
$status = @{
mysqlHost = "127.0.0.1"
mysqlDb = "inquiry_robot"
mysqlCreated = $true
pgHost = "127.0.0.1"
pgDb = "inquiry_robot_runtime"
pgCreated = $true
note = "Empty DBs on APP-SERVER local instances. MySQL via skip-grant maintenance; root secret in ops/local_mysql_root_secret.json. Not 10.206.0.14."
updatedAt = (Get-Date).ToString("o")
needDba = $false
} | ConvertTo-Json
Set-Content (Join-Path $ops "data-plane-status.json") -Value $status -Encoding UTF8
Write-Output $status
Write-Output "CREATE_ALL_DONE"