| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172 |
- [CmdletBinding()]
- param(
- [string]$ContainerName = "zhibaotong-mysql"
- )
- $ErrorActionPreference = "Stop"
- $ProjectRoot = Split-Path -Parent $PSScriptRoot
- $SqlPath = Join-Path $ProjectRoot "database\mysql.sql"
- $ContainerSqlPath = "/tmp/zbt-init.sql"
- if (-not (Test-Path -LiteralPath $SqlPath)) {
- throw "缺少数据库快照:$SqlPath"
- }
- if ($null -eq (Get-Command docker -ErrorAction SilentlyContinue)) {
- throw "未找到 Docker 命令,请先安装并启动 Docker Desktop。"
- }
- docker inspect $ContainerName *> $null
- if ($LASTEXITCODE -ne 0) {
- throw "未找到 MySQL 容器 $ContainerName。可通过 -ContainerName 指定实际容器名。"
- }
- $Running = docker inspect --format '{{.State.Running}}' $ContainerName
- if ($LASTEXITCODE -ne 0) {
- throw "无法读取 MySQL 容器 $ContainerName 的运行状态。"
- }
- if ($Running.Trim() -ne "true") {
- docker start $ContainerName | Out-Null
- if ($LASTEXITCODE -ne 0) {
- throw "MySQL 容器 $ContainerName 启动失败。"
- }
- }
- # MySQL 首次创建容器时会先启动临时实例初始化系统表,随后再启动正式实例。
- # 要求连续多次响应,避免 SQL 恰好导入到临时实例与正式实例的切换窗口。
- $Ready = $false
- $ConsecutiveSuccesses = 0
- for ($Attempt = 1; $Attempt -le 90; $Attempt++) {
- docker exec $ContainerName sh -c 'mysqladmin ping -uroot -p"$MYSQL_ROOT_PASSWORD" --silent >/dev/null 2>&1'
- if ($LASTEXITCODE -eq 0) {
- $ConsecutiveSuccesses++
- if ($ConsecutiveSuccesses -ge 5) {
- $Ready = $true
- break
- }
- }
- else {
- $ConsecutiveSuccesses = 0
- }
- Start-Sleep -Seconds 1
- }
- if (-not $Ready) {
- throw "MySQL 容器 $ContainerName 在 90 秒内未就绪。"
- }
- try {
- docker cp $SqlPath "${ContainerName}:$ContainerSqlPath"
- if ($LASTEXITCODE -ne 0) {
- throw "数据库快照复制到容器失败。"
- }
- docker exec $ContainerName sh -c 'mysql -uroot -p"$MYSQL_ROOT_PASSWORD" --default-character-set=utf8mb4 < /tmp/zbt-init.sql'
- if ($LASTEXITCODE -ne 0) {
- throw "数据库快照导入失败,请检查容器中的 MYSQL_ROOT_PASSWORD。"
- }
- Write-Host "第三阶段 MySQL 数据初始化完成。" -ForegroundColor Green
- }
- finally {
- docker exec $ContainerName rm -f $ContainerSqlPath *> $null
- }
|