---
id: 134c150de56c188c925476664026a1ff
author: Lemon Mint
title: 'gosuda.org/sqlite3: CGO_ENABLED=0 database/sql Sürücüsü, Paylaşımlı Bellek IPC Üzerinden'
description: CGO_ENABLED=0 ile çalışan, HQQ paylaşımlı bellek işçi izolasyonu, 64 KiB toplu satır ön yüklemesi ve SLSA ile onaylanmış ikili dosyalar sunan, Go için database/sql uyumlu SQLite 3.54.1 sürücüsü.
language: tr
date: 2026-10-18T14:02:16.803040007Z
path: /sqlite3
go_package: gosuda.org/sqlite3
go_repourl: https://github.com/gosuda/hqq-sqlite3.git
category: database
---

`gosuda.org/sqlite3`, `CGO_ENABLED=0` ile çalışan ve Go için bir `database/sql` sürücüsüdür; upstream C SQLite `3.54.1` amalgamation kodunu, [HQQ](https://gosuda.org/hqq) paylaşımlı bellek halkaları üzerinden izole bir worker süreci içinde çalıştırır. Standart `"sqlite3"` sürücü adıyla kayıt olur, `github.com/mattn/go-sqlite3` DSN sorgu parametrelerini destekler, altı işletim sistemi ve mimari hedefi için SLSA ile doğrulanmış önceden derlenmiş sunucu ikili dosyalarını gömülü olarak içerir ve 64 KiB toplu ön getirme (batch prefetching) ile istek boru hattı (request pipelining) kullanarak çok satırlı sorgularda süreç içi `cgo` çözümünden daha yüksek performans sağlar.

```bash
go get gosuda.org/sqlite3@v0.3.3540100
```

## Neden Bir Go SQLite Sürücüsü Daha?

SQLite, dünyada en yaygın kullanılan yazılımlardan biridir; ancak Go'dan kullanımı tarihsel olarak mühendisleri derleme basitliği ile motor sadakati arasında rahatsız edici bir seçim yapmaya zorlamıştır.

Bir yanda, uzun süredir topluluğun standardı olan `github.com/mattn/go-sqlite3` bulunmaktadır. Resmi C SQLite amalgamation kodunu doğrudan `cgo` aracılığıyla sarmalar. Gerçek C sorgu planlayıcısını, tam WAL eşzamanlılık semantiğini ve öngörülebilir C bellek yönetimini elde edersiniz. Bedeli ise `CGO_ENABLED=1` gerekliliğidir: yerel derlemeler ve CI hatları yavaşlar, minimal scratch veya distroless konteyner imajları uyumlu C çalışma zamanı kütüphaneleri gerektirir, başka bir işletim sistemine veya CPU mimarisine çapraz derleme tam bir C çapraz araç zinciri gerektirir ve C içindeki herhangi bir bellek bozulması Go süreci adres alanını paylaşır.

Diğer yanda, C amalgamation kodunun bir öykünülmüş C çalışma zamanı (`libc`) üzerinden Go kaynak koduna mekanik olarak çevrilmesiyle üretilen saf Go SQLite portları vardır. Bunlar `CGO_ENABLED=0` desteğini geri getirir ve derlemeyi basitleştirir. Ancak sürekli iş yüklerinde, çevrilmiş C yığını ve satır başına Go ayırmaları çöp toplama baskısını artırır ve kilitleme, meşgul zaman aşımları veya ifade kesintisi gibi ince uç durumlar yerel C derlemelerinden ayrışabilir.

`gosuda.org/sqlite3` kütüphanesini, Go uygulamalarının `CGO_ENABLED=0` ile gerçek C SQLite motoru arasında seçim yapmak zorunda kalmaması için oluşturduk. Resmi SQLite `3.54.1` C amalgamation kodunu, özel bir paylaşımlı bellek sunucusuna (`hqq-sqlite-server`) derleyerek ve `gosuda.org/hqq` üzerinden iletişim kurarak, Go ikili dosyanız `CGO_ENABLED=0` ile derlenirken, değiştirilmemiş, `-O3` ile optimize edilmiş C SQLite'ı bir süreç sınırının ötesinde çalıştırır.

## Sıfır Yapılandırmalı Çalıştırma: `go get` Komutundan `sql.Open` Çağrısına

Mevcut bir Go kod tabanında `github.com/mattn/go-sqlite3` kütüphanesini değiştirmek yalnızca boş (blank) içe aktarma yolunun değiştirilmesini gerektirir. Sürücü `"sqlite3"` adıyla (ve açık seçim için `"hqq-sqlite"` adıyla) kayıt olur ve aynı DSN sorgu dizgelerini kabul eder:

```go
package main

import (
	"context"
	"database/sql"
	"fmt"
	"log"

	_ "gosuda.org/sqlite3"
)

func main() {
	dsn := "file:app.db?_journal_mode=WAL&_busy_timeout=5000&_txlock=immediate&_foreign_keys=on"
	db, err := sql.Open("sqlite3", dsn)
	if err != nil {
		log.Fatal(err)
	}
	defer db.Close()

	ctx := context.Background()
	if _, err := db.ExecContext(ctx, `CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT NOT NULL)`); err != nil {
		log.Fatal(err)
	}
	if _, err := db.ExecContext(ctx, `INSERT INTO users (name) VALUES (?)`, "Ada Lovelace"); err != nil {
		log.Fatal(err)
	}

	var id int64
	var name string
	if err := db.QueryRowContext(ctx, `SELECT id, name FROM users WHERE name = ?`, "Ada Lovelace").Scan(&id, &name); err != nil {
		log.Fatal(err)
	}
	fmt.Printf("user #%d: %s\n", id, name)
}
```

### Gömülü SLSA ile Doğrulanmış Worker İkili Dosyaları

Bir kütüphanenin C worker süreci kullandığını duyduğunuzda akla gelen doğal bir soru şudur: _"Go programımın yanında ayrı bir C ikili dosyasını kurmam veya dağıtmam gerekir mi?"_

Hayır. `gosuda.org/sqlite3`, altı ana hedefin tümü için önceden derlenmiş `hqq-sqlite-server` ikili dosyalarını, platforma göre etiketlenmiş Go dosyalarının (`internal/embedded/embed_<goos>_<goarch>.go`) içine doğrudan gömer. Go'nun derleme kısıtlamaları yalnızca hedef `GOOS` ve `GOARCH` değerinizle eşleşen dosyayı derlediğinden, `GOOS=linux GOARCH=arm64 go build` komutuyla çapraz derleme yapmak yalnızca yaklaşık 1,4 MiB boyutundaki `linux/arm64` sunucu ikili dosyasını otomatik olarak gömer.

| Hedef İşletim Sistemi | Hedef Mimari (`GOARCH`) | Gömülü İkili Dosya                    | Derleme Araç Zinciri ve Köken                     |
| :-------------------- | :---------------------- | :------------------------------------ | :------------------------------------------------ |
| **Linux**             | `amd64`, `arm64`        | `hqq-sqlite-server_linux_<arch>`      | GCC `-O3`, SLSA Build L3 Provenance               |
| **macOS**             | `arm64`, `amd64`        | `hqq-sqlite-server_darwin_<arch>`     | AppleClang `-O3`, SLSA Build L3 Provenance        |
| **Windows**           | `amd64`                 | `hqq-sqlite-server_windows_amd64.exe` | MSVC `-O2`, SLSA Build L3 Provenance              |
| **Windows**           | `arm64`                 | `hqq-sqlite-server_windows_arm64.exe` | `zig cc -target aarch64-windows-gnu -O3`, SLSA L3 |

`sql.Open` ilk bağlantısını kurduğunda, `autolaunch.go` gömülü ikili dosyayı kullanıcı önbellek dizinine (`$XDG_CACHE_HOME/hqq/bin/<sha256>/`) yazar, kriptografik SHA-256 özetini `hashes.go` içindeki sabitlenmiş `ReleaseHashes` haritasına karşı `gosuda.org/hqq/secureexec` aracılığıyla doğrular ve worker'ı `--parent-stdin` parametresiyle başlatır; böylece yaşam süresi kesin olarak Go süreciniz ile sınırlandırılır.

### Temiz Oda (Clean-Room) `mattn/go-sqlite3` DSN Uyumluluğu

Gerçek bir doğrudan yerine geçen (drop-in) çözüm olabilmek için DSN ayrıştırıcısı (`dsn.go`), `mattn/go-sqlite3` kod tabanlarında kullanılan bağlantı ve pragma ayarlarının temiz oda bir kopyasını uygular:

| DSN Sorgu Parametresi | Kabul Edilen Değerler | SQLite Etkisi |
| :-------------------- | :-------------------- | :------------ |
| `_busy_timeout` / `_timeout` | Milisaniye cinsinden tamsayı (ör. `5000`) | Oturum açılışında `sqlite3_busy_timeout(db, ms)` çağrısını yapar. |
| `_journal_mode` / `_journal` | `DELETE`, `TRUNCATE`, `PERSIST`, `MEMORY`, `WAL`, `OFF` | `PRAGMA journal_mode = <mode>` ifadesini çalıştırır. |
| `_txlock` | `immediate`, `exclusive`, `deferred` | `db.BeginTx` için `BEGIN IMMEDIATE`, `BEGIN EXCLUSIVE` veya `BEGIN DEFERRED` seçer. |
| `_foreign_keys` / `_fk` | `on`, `true`, `1`, `off`, `false`, `0` | `PRAGMA foreign_keys = ON/OFF` ifadesini çalıştırır. |
| `_synchronous` / `_sync` | `0`/`OFF`, `1`/`NORMAL`, `2`/`FULL`, `3`/`EXTRA` | `PRAGMA synchronous = <level>` ifadesini çalıştırır. |
| `_cache_size` | Tamsayı sayfa veya `-KiB` (ör. `-20000`) | `PRAGMA cache_size = <val>` ifadesini çalıştırır. |
| `_loc` | `auto` veya IANA saat dilimi (ör. `UTC`, `Asia/Seoul`) | `DATETIME`/`TIMESTAMP` metin sütunlarını hedef konumda `*time.Time` değerlerine ayrıştırır. |
| `mode` | `ro`, `rw`, `rwc`, `memory` | `SQLITE_OPEN_READONLY`, `SQLITE_OPEN_READWRITE`, `SQLITE_OPEN_CREATE` veya `SQLITE_OPEN_MEMORY` bayraklarını ayarlar. |
| `_case_sensitive_like`, `_query_only`, `_recursive_triggers`, `_secure_delete`, `_AutoVacuum` | Boolean veya mod tamsayıları | Bağlantı başlatmada ilgili oturum `PRAGMA` ifadesini uygular. |

## Süreç Yalıtımını Bir Verim Avantajına Dönüştürmek

İlk bakışta SQLite'ı ayrı bir süreçte çalıştırmak, `cgo` üzerinden süreç içinde `sqlite3_step` çağırmaktan daha yavaş gibi görünebilir. Pratikte, bir sorgu birden fazla satır döndürdüğü anda tam tersi gerçekleşir.

### Satır Satır `cgo` Çağrılarının Gizli Maliyeti

Geleneksel bir `cgo` SQLite sürücüsünde `database/sql`, yinelemeyi bir seferde bir satır ve bir sütun olacak şekilde yönetir. 4 sütunlu 1.000 satırın okunması şunları tetikler:

- `sqlite3_step` için 1.000 `cgo` çağrısı
- `sqlite3_column_type` ile `sqlite3_column_int64` / `sqlite3_column_text` için 4.000 `cgo` çağrısı
- Go zamanlayıcısı ile C yığını arasında binlerce ayrı sınır geçişi

### İstek Boru Hattı ve 64 KiB Toplu Ön Getirme

`gosuda.org/sqlite3`, `stmt.go`, `rows.go` ve `sqlite3/server/sqlite3_hooks.c` dosyalarındaki iki mekanizma etrafında kablo protokolünü yeniden tasarlayarak satır başına sınır geçişlerini ortadan kaldırır:

```text
Go İstemcisi (stmt.go / rows.go)                    C11 Worker (sqlite3_hooks.c)
-----------------------------                       ----------------------------
1. Tek uçuşta boru hattı:
   ResetAsync + BindValuesAsync
   + StmtInfoAsync + FetchRowsAsync(128)  =======>  reset -> bind -> stmt_info ->
                                                    128 satıra kadar sqlite3_step() döngüsü
                                          <=======  Toplu 1 (satır 1..128, 64 KiB slotta paketlenmiş)
2. Hemen ön getirmeyi başlat:
   FetchRowsAsync(128) (Toplu 2)          =======>  129..256 satırları için sqlite3_step() döngüsü
   C, Toplu 2'yi adımlarken Go çağıran
   kod, Toplu 1'deki 1..128 satırlarını tarar!  <=======  Toplu 2 paylaşımlı bellekte hazır
```

1. **Tek Uçuşlu Sorgu Boru Hattı (`stmt.go`)**: `QueryContext` veya `Stmt.QueryContext`, salt okunur bir ifadeyi çalıştırdığında, `s.query()` işlevi `reset`, `bind_values`, `stmt_info` (ilk çalıştırmada) ve `fetch_rows` işlemlerini tek bir paylaşımlı bellek uçuşunda eşzamansız olarak gönderir. Dört işlemin tümü C worker üzerinde art arda çalışır ve tek bir gidiş-dönüşte geri döner.
2. **Sıkı C Toplu Döngüleri ve Eşzamansız Ön Getirme (`rows.go`)**: `fetch_rows` (`sqlite3_hooks.c`) içinde C worker, yerel bir C döngüsünde `sqlite3_step(stmt)` çağırır ve toplu sınırına, slotun dolmasına veya `SQLITE_DONE` durumuna ulaşılana kadar en fazla `FetchSize` (varsayılan 128) satırı doğrudan 64 KiB paylaşımlı bellek yanıt slotuna kodlar. `rows.ingest()` Toplu 1'i çözer çözmez, ilk satırı çağırana döndürmeden önce Toplu 2 için `FetchRowsAsync` çağrısını başlatır. Go kodunuz Toplu 1'i tararken, C worker Toplu 2'yi başka bir CPU çekirdeğinde zaten adımlamaktadır.

Apple M4 (`darwin/arm64`) üzerinde, aynı SQLite veritabanı kullanılarak `gosuda.org/sqlite3` (`CGO_ENABLED=0`) ile `github.com/mattn/go-sqlite3` (`CGO_ENABLED=1`) karşılaştırıldığında, toplu işlemenin ve boru hattının etkisi görülmektedir:

| İş Yükü | `gosuda.org/sqlite3` (`CGO_ENABLED=0`) | `mattn/go-sqlite3` (`CGO_ENABLED=1`) | Göreli Hız |
| :------ | -------------------------------------: | -----------------------------------: | :--------- |
| **Nokta Seçimi (`QueryRow`, birincil anahtar ile)** | `3.52 µs/op` (9 B, 1 ayırma) | `3.56 µs/op` (232 B, 11 ayırma) | **1.01x (eşit, 11 kat az ayırma)** |
| **100 Satırlık Tarama (`rows.Next`)** | `20.41 µs/op` (30.5 KB, 211 ayırma) | `36.34 µs/op` (21.8 KB, 309 ayırma) | **1.78x daha hızlı** |
| **1.000 Satırlık Tarama (`rows.Next`)** | `125.92 µs/op` (296 KB, 2.030 ayırma) | `349.10 µs/op` (216 KB, 3.009 ayırma) | **2.77x daha hızlı** |
| **Hazırlanmış Ekleme (Otomatik İşlem)** | `5.33 µs/op` (0 B, 0 ayırma) | `5.88 µs/op` (120 B, 5 ayırma) | **1.10x daha hızlı (0 ayırma)** |
| **100 Satırlık İşlem Toplu İşlemi** | `189.99 µs/op` (16 B, 1 ayırma) | `191.50 µs/op` (12.1 KB, 503 ayırma) | **1.01x (500 kat az ayırma)** |

## İptal, Yol Kumlaması ve Bağlantı Havuzu Kurtarma

İzole bir worker içinde SQLite çalıştırmak, sürücünün zaman aşımlarını, güvenilmeyen SQL'i ve dosya sistemi sınırlarını ele alma biçimini de güçlendirir:

- **Deterministik Bağlam İptali (`conn.go` ve `errors.go`)**: Her sürücü çağrısı hafif bir `context.AfterFunc` koruyucusu (`cn.guard`) kurar. Sunucuda yavaş bir özyinelemeli sorgu veya kilit beklemesi çalışırken çağıranın `context.Context` değeri iptal edilir veya süresi dolarsa, koruyucu bağlantıyı bozuk olarak işaretler, yerel oturum bağlantısını sonlandırır ve bant dışı bir `Cancel()` çerçevesi gönderir. C worker, `sqlite3_step` işlemini engelleyen `sqlite3_interrupt(db)` çağrısını hemen yapar; Go sürücüsü ise ortaya çıkan `SQLITE_INTERRUPT` durumunu `context.Canceled` veya `context.DeadlineExceeded` değerlerine eşler ve `database/sql` paketine bağlantıyı havuzda değiştirmesi talimatını verir.
- **Dizin Kumlaması (`sqlsrv_pathrules.c`)**: C worker, her `open_v2` çağrısında `--allow-dir` yol kurallarını uygular; sembolik bağlantıları çözümler ve izin verilen dizin dışına yapılan göreli `..` geçişlerini reddeder. `sqlite3_load_extension` ve `SQLITE_LIMIT_ATTACHED` varsayılan olarak devre dışıdır; böylece SQL enjeksiyonu veritabanı dizininden kaçamaz veya rastgele paylaşımlı nesneleri yükleyemez.

## Depo Yapısı

Depo, en üst düzey paketin doğrudan kullanılabilir `database/sql` sürücüsünü sağlayacak, `launcher/` ve `sqlite3/` ise gelişmiş özel sunucu dağıtımları için erişilebilir kalacak şekilde düzenlenmiştir:

```text
gosuda.org/sqlite3
├── driver.go / api.go         # database/sql sürücü kaydı ("sqlite3") ve Connector API
├── dsn.go                     # Temiz oda mattn/go-sqlite3 DSN ayrıştırıcısı ve pragma yapılandırması
├── conn.go / tx.go            # Oturum yaşam döngüsü, bağlam koruyucusu ve işlem durum makinesi
├── stmt.go / rows.go          # Tek uçuşlu istek boru hattı ve 64 KiB toplu ön getirme
├── errors.go                  # Tiplenmiş SQLite birincil/genişletilmiş hata kodları ve sentinel eşleştirme
├── autolaunch.go / hashes.go  # Sıfır yapılandırmalı gömülü sunucu açığa çıkarma ve SHA-256 sabitleme
├── internal/embedded/         # Platforma göre etiketlenmiş //go:embed ikili dosyaları (linux, darwin, windows)
├── launcher/                  # Özel sunucu dağıtımları için yapılandırılabilir süreç denetleyicisi
└── sqlite3/                   # Üretilmiş hqq-bindgen Go istemcisi ve C11 SQLite sunucu kaynağı
    └── server/                # C11 sunucu uygulaması (sqlite3_hooks.c, sqlsrv_policy.c)
```

## Başlarken

Modülü `go get` ile kurun ve veritabanınızı `sql.Open("sqlite3", dsn)` ile açın:

```bash
go get gosuda.org/sqlite3@v0.3.3540100
```

- **GitHub Deposu**: [https://github.com/gosuda/hqq-sqlite3](https://github.com/gosuda/hqq-sqlite3)
- **DSN ve Pragma Referansı**: [docs/DSN.md](https://github.com/gosuda/hqq-sqlite3/blob/main/docs/DSN.md)
- **Mimari ve Kablo Protokolü**: [docs/ARCHITECTURE.md](https://github.com/gosuda/hqq-sqlite3/blob/main/docs/ARCHITECTURE.md)
