惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

S
Schneier on Security
博客园 - 【当耐特】
人人都是产品经理
人人都是产品经理
大猫的无限游戏
大猫的无限游戏
Last Week in AI
Last Week in AI
IT之家
IT之家
V
V2EX
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
博客园 - 叶小钗
Martin Fowler
Martin Fowler
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
M
MIT News - Artificial intelligence
博客园 - 聂微东
MyScale Blog
MyScale Blog
云风的 BLOG
云风的 BLOG
The Cloudflare Blog
WordPress大学
WordPress大学
Microsoft Azure Blog
Microsoft Azure Blog
阮一峰的网络日志
阮一峰的网络日志
酷 壳 – CoolShell
酷 壳 – CoolShell
博客园 - 三生石上(FineUI控件)
Cyberwarzone
Cyberwarzone
Scott Helme
Scott Helme
H
Help Net Security
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
The GitHub Blog
The GitHub Blog
Cisco Talos Blog
Cisco Talos Blog
D
DataBreaches.Net
P
Palo Alto Networks Blog
T
Threatpost
P
Privacy & Cybersecurity Law Blog
L
LINUX DO - 最新话题
Know Your Adversary
Know Your Adversary
C
CXSECURITY Database RSS Feed - CXSecurity.com
B
Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
P
Proofpoint News Feed
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Cloudbric
Cloudbric
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
N
News and Events Feed by Topic
T
The Blog of Author Tim Ferriss
L
Lohrmann on Cybersecurity
量子位
Security Latest
Security Latest
Google DeepMind News
Google DeepMind News
Y
Y Combinator Blog
aimingoo的专栏
aimingoo的专栏
Forbes - Security
Forbes - Security
T
Tailwind CSS Blog

alexwlchan’s notes

Disable the new message animations in WhatsApp Finding high-churn folders that bother Backblaze Always-on SSH agent forwarding with my Git pushes Managing the caption of a photo with AppleScript (but not PhotoKit) Goodhart’s and Campbell’s Law are different Notes from The Cornishman No. 176 (Spring 2026) Notes from The Cornishman No. 176 (Spring 2026) GitUp can’t diff text files larger than 8MB Home Testing the width of a page on a mobile device using Playwright Disable AirPods charging notifications Start a Caddy server in a subprocess during a Python session Filter a list of JSON object based on a list of tags HOME_GET_ME_HOME is a Citymapper Shortcuts action The FileExistsError exception exposes a filename attribute The red-lined bubble snail Why can’t Python connect to example.com? Useful type hints for Python How to truncate the middle of long command output AirPlay Receiver can interfere with Flask apps What’s the main prefix in SQLite queries? My randline project is tested by Crater Drawing an image with Liquid Glass using SwiftUI Previews Road signs in the Soviet union don’t have circular heads Setting up golink in my personal tailnet Create a file atomically in Go Get a map of IP addresses for devices in my tailnet The SQLite command line shell will count your unclosed parentheses Use SQL triggers to prevent overwriting a value Testing date formatting with date-fns-tz and different timezones The “strangler” pattern is named after a tree, not an act of violence Place with the same name, but different etymology
The file(1) command can read SQLite databases
2026-03-14 · via alexwlchan’s notes

It can identify a SQLite database and give you basic information about the version, page count, encoding, and more.

Here’s a neat trick that Percy showed me today: the file(1) command is able to recognise SQLite databases, and print some information about the structure of the database.

Here’s an example from my Mac:

$ file example.db
example.db: SQLite 3.x database, last written using SQLite version 3050004, file counter 89, database pages 4, cookie 0x2, schema 4, UTF-8, version-valid-for 89

These values are read from the database header, the first 100 bytes of the file which include information about the database. A couple of fields stood out to me:

  • The SQLite version. This is an integer, specifically SQLITE_VERSION_NUMBER, which is a representation of the version number. In this example, 3050004 means the database was last written by SQLite 3.50.4.

  • The file (change) counter counts changes to the database. If multiple processes are working in the same database, they can detect when another process made a change, and invalidate their page cache.

    I was surprised that this value was so low for our production databases at work (just 1196), but the SQLite docs explain that if you run your database in WAL mode – which we do – changes are tracked through the wal-index, and so the change counter might not be incremented. That must be happening in our databases.

  • The (schema) cookie gets incremented whenever the database schema changes. I ran a quick example and I can see it increasing from 0x2 to 0x3 in my example database:

    $ file example.db
    example.db: SQLite 3.x database, last written using SQLite version 3050004, file counter 90, database pages 4, cookie 0x2, schema 4, UTF-8, version-valid-for 90
    
    $ sqlite3 example.db 'CREATE TABLE NewTable(x);'
    
    $ file example.db
    example.db: SQLite 3.x database, last written using SQLite version 3050004, file counter 91, database pages 5, cookie 0x3, schema 4, UTF-8, version-valid-for 91

    The field that file(1) labels as “schema” is the schema format number, and tracks the version of SQL formatting used in the database. As of 13 March 2026, schema format 4 is the highest possible value, and it has been since January 2006.

  • The user version field is an integer for “applications to use however they want” which SQLite doesn’t read. I imagine this might be quite useful for storing, say, a schema version in an easily accessible location.

    You can set it using the user_version pragma, and then it appears in the file(1) output:

    $ sqlite3 example.db 'PRAGMA user_version = 42;'
    
    $ file example.db
    example.db: SQLite 3.x database, user version 42, last written using SQLite version 3050001, file counter 92, database pages 5, cookie 0x3, schema 4, UTF-8, version-valid-for 92
  • The application ID is a field to identify the application that “owns” the database. Lots of applications use SQLite as their storage format, and they can record their ID in this field.

    There are well-known values in magic.txt in the SQLite repository. If you use one of these, file(1) adds the human-readable name to its output:

    $ sqlite3 example.db 'PRAGMA application_id = 0x0f055112;'
    
    $ file example.db
    example.db: SQLite 3.x database (Fossil checkout), last written using SQLite version 3050001, file counter 94, database pages 5, cookie 0x3, schema 4, UTF-8, version-valid-for 94

    If you use a different value, file(1) prints the literal value:

    $ sqlite3 example.db 'PRAGMA application_id = 0x42424242;'
    
    $ file example.db
    example.db: SQLite 3.x database, application id 1111638594, last written using SQLite version 3050001, file counter 95, database pages 5, cookie 0x3, schema 4, UTF-8, version-valid-for 95

    This lookup comes from a sql “magic” file which ships with file(1), embedding all the values from SQLite’s magic.txt and many more besides.