You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Goroutine批量导入CSV至PostgreSQL时遇切片越界Panic

嘿,这个切片拆分的坑我之前也踩过!咱们先搞清楚问题出在哪,再给你解决办法。

首先,你遇到的runtime error: slice bounds out of range本质是整数除法的向下取整特性导致的。假设你有13个CSV文件要拆成10份:len(fis)/10等于1(Go里整数除法会直接丢掉小数部分),如果按固定每份1个来拆分,前9份各拿1个,剩下的3个文件没被处理;但如果你的代码逻辑是强制拆成10份,每份都按len(fis)/10的长度去取,当最后一份的结束索引超过切片总长度时,就会触发panic——比如总文件数是9、goroutine数是10时,第10个goroutine的切片范围会超出原切片的长度。

正确的拆分方式

核心思路是:先计算每份的基础长度,再把无法整除的余数均匀分配给前几份(每份多1个文件),确保所有文件都被覆盖,且不会超出切片范围。

给你一段修正后的代码示例:

package main

import (
    "os"
    "sync"
)

func main() {
    gophers := 10
    // 假设你已经获取到了所有CSV文件的FileInfo列表
    fis, err := os.ReadDir("/path/to/csvs")
    if err != nil {
        panic(err)
    }
    fileInfos := make([]os.FileInfo, len(fis))
    for i, f := range fis {
        fileInfos[i], _ = f.Info()
    }

    totalFiles := len(fileInfos)
    chunkSize := totalFiles / gophers
    remainder := totalFiles % gophers // 无法整除的剩余文件数

    var wg sync.WaitGroup

    for i := 0; i < gophers; i++ {
        start := i * chunkSize
        // 给前remainder个goroutine多分配1个文件
        end := start + chunkSize
        if i < remainder {
            end++
        }
        // 保险起见,确保end不会超过总文件数(其实上面的逻辑已经避免了)
        if end > totalFiles {
            end = totalFiles
        }
        // 跳过空的chunk(比如总文件数小于goroutine数时)
        if start >= end {
            continue
        }

        chunk := fileInfos[start:end]
        wg.Add(1)
        go func(files []os.FileInfo) {
            defer wg.Done()
            // 这里写你的CSV读取+PostgreSQL导入逻辑
            for _, fi := range files {
                filePath := "/path/to/csvs/" + fi.Name()
                // 1. 读取CSV文件内容到对象
                // 2. 批量插入PostgreSQL(建议用事务提高性能)
            }
        }(chunk)
    }

    // 等待所有goroutine完成导入
    wg.Wait()
}

额外的优化建议

  1. 数据库批量插入:不要每个CSV文件单独开事务,尽量把多个文件的数据攒成一批再插入,减少数据库连接开销,提高导入速度。
  2. 错误处理:上面的示例简化了错误处理,实际代码中要捕获CSV读取、数据库操作的错误,避免某个goroutine出错导致整个导入流程静默失败。
  3. 资源限制:如果CSV文件非常大,要注意内存占用,必要时可以分批次读取文件内容,而不是一次性加载到内存。

这样拆分的话,不管总文件数能不能被10整除,都不会出现切片越界的问题,所有文件都会被均匀分配给各个goroutine处理。

内容的提问来源于stack exchange,提问作者MarcoW

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:05:07