百科.dev
全部条目AI 编程趋势榜开源项目技术资讯提交条目
登录
< 返回工具列表
M

maxminddb-golang

> 编程语言
开源

适用于 Go 的 MaxMind DB Reader

735 stars0 点赞0 次浏览
访问官网GitHub

工具介绍

适用于 Go 的 MaxMind DB Reader

MaxMind DB Reader for Go

This is a Go reader for the MaxMind DB format. Although this can be used to read GeoLite2 and GeoIP2 databases, geoip2 provides a higher-level API for doing so.

This is not an official MaxMind API.

Installation

go get github.com/oschwald/maxminddb-golang/v2

Version 2 Features

Version 2 includes significant improvements:

  • Modern API: Uses netip.Addr instead of net.IP for better performance
  • Custom Unmarshaling: Implement CursorUnmarshaler for reflection-free custom decoding
  • Network Iteration: Iterate over all networks in a database with Networks() and NetworksWithin()
  • Enhanced Performance: Optimized data structures and decoding paths
  • Better Error Handling: More detailed error types and improved debugging
  • Integrity Checks: Validate databases with Reader.Verify() and access metadata helpers such as Metadata.BuildTime()

See MIGRATION.md for guidance on updating existing v1 code.

Quick Start

…

Usage Patterns

Basic Lookup

db, err := maxminddb.Open("GeoLite2-City.mmdb")
if err != nil {
	log.Fatal(err)
}
defer db.Close()

var record any
ip := netip.MustParseAddr("1.2.3.4")
err = db.Lookup(ip).Decode(&record)

Untrusted Database Files

Call Reader.Verify once immediately after opening an untrusted database and before performing lookups or decoding records:

if err := db.Verify(); err != nil {
	log.Fatal(err)
}

Verification applies to the database contents at the time of the call. Keep those contents immutable for the Reader's lifetime: do not modify a slice passed to OpenBytes or rewrite or truncate a memory-mapped file in place. Open and verify a new Reader when publishing an updated database.

Reflection decoding limits each operation to 32,768 declared container child slots; map keys and values each consume one slot. Maps and slices reserve their children before allocation or traversal. Materialized string and byte payloads also have an operation-wide bound: every delivered payload byte draws from a shared 2 MiB allowance. Materialized map keys and keys inspected by DecodePath draw their full size from the same payload allowance.

Decoding into any activates these limits even when the root is a scalar. A standalone scalar decoded into a directly typed destination or a named empty-interface type remains unbudgeted because it cannot amplify. A non-empty DecodePath shares one set of limits between path navigation and the selected value. Skipping an unknown field still charges any inline containers, but does not follow pointer targets or charge payload that is not materialized. Custom unmarshalers and low-level cursor traversal control and must bound their own work; Reader.Verify validates the complete data section and the original metadata graph, including unknown metadata fields, before those APIs are used with untrusted input.

Custom Struct Decoding

type City struct {
	Country struct {
		ISOCode string `maxminddb:"iso_code"`
		Names   struct {
			English string `maxminddb:"en"`
			German  string `maxminddb:"de"`
		} `maxminddb:"names"`
	} `maxminddb:"country"`
	Subdivisions []struct {
		ISOCode string `maxminddb:"iso_code"`
	} `maxminddb:"subdivisions,maxsize:32"`
}

var city City
err = db.Lookup(ip).Decode(&city)

The maxsize:N tag option rejects a matching MMDB map or array with more than N entries, or a matching string or byte value with more than N bytes. An MMDB array decoded into []byte is covered as well. The check happens before the matching field is allocated or mutated and is supported by both reflection decoding and maxminddb-gen. Tag options use the encoding/json/v2 comma and colon grammar, for example maxminddb:"subdivisions,maxsize:32". Because a comma delimits options, quote a literal field name containing a comma with the same grammar, for example maxminddb:"'city,name'". For a supported custom field type, maxsize checks every size-bearing MMDB kind (map, array, string, and bytes) before invoking the unmarshaler because the encodings accepted by a callback cannot be inferred from its Go type.

High-Performance Custom Unmarshaling

For application-owned structs, maxminddb-gen can generate an UnmarshalMaxMindDBCursor method that avoids reflection. The generator is versioned with this module and remains optional; types with neither generated nor handwritten custom unmarshaling methods continue to use reflection.

Add the tool to the consuming module's go.mod and add a generation directive in the package that owns the target types:

tool github.com/oschwald/maxminddb-golang/v2/maxminddb-gen
//go:generate go tool maxminddb-gen $GOFILE

This discovers the exported structs declared in the directive's source file. For models.go, it writes models_maxminddb.go; recognized build suffixes and source build constraints are preserved. Constrained inputs must match the generation environment; multiple inputs share the intersection of their constraints. Use -output to override the default. Run go generate ./... and check the generated file into source control. See maxminddb-gen/README.md for supported types, diagnostics, and reproducible CI usage.

For new handwritten decoders, implement mmdbdata.CursorUnmarshaler. Cursor reads return an opaque successor positioned after the decoded value, allowing nested custom decoding to continue without rescanning it.

The older UnmarshalMaxMindDB(*mmdbdata.Decoder) error callback is deprecated. It remains supported throughout v2 but is planned for removal in v3; see GitHub #224. When a type implements both callbacks, UnmarshalMaxMindDBCursor takes precedence.

Custom unmarshalers control their own traversal and allocation. If a database is not trusted, an implementation should use one aggregate per-record work budget across nested calls. The budget should cover recursion, collection entries, repeated pointer targets, and produced string or byte payloads; the reflection decoder's expansion guard is not applied inside custom callbacks.

type Label string

func (label *Label) UnmarshalMaxMindDBCursor(
	cursor mmdbdata.Cursor,
) (mmdbdata.Cursor, error) {
	value, next, err := cursor.ReadString()
	if err != nil {
		return mmdbdata.Cursor{}, mmdbdata.NormalizeUnmarshalError[Label](err)
	}
	*label = Label(value)
	return next, nil
}

Network Iteration

// Iterate over all networks in the database
for result := range db.Networks() {
	var record struct {
		Country struct {
			ISOCode string `maxminddb:"iso_code"`
		} `maxminddb:"country"`
	}
	err := result.Decode(&record)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s: %s\n", result.Prefix(), record.Country.ISOCode)
}

// Iterate over networks within a specific prefix
prefix := netip.MustParsePrefix("192.168.0.0/16")
for result := range db.NetworksWithin(prefix) {
	// Process networks within 192.168.0.0/16
}

Path-Based Decoding

var countryCode string
err = db.Lookup(ip).DecodePath(&countryCode, "country", "iso_code")

var cityName string
err = db.Lookup(ip).DecodePath(&cityName, "city", "names", "en")

Supported Database Types

This library supports all MaxMind DB (.mmdb) format databases, including:

MaxMind Official Databases:

  • GeoLite/GeoIP City: Comprehensive location data including city, country, subdivisions
  • GeoLite/GeoIP Country: Country-level geolocation data
  • GeoLite ASN: Autonomous System Number and organization data
  • GeoIP Anonymous IP: Anonymous network and proxy detection
  • GeoIP Enterprise: Enhanced City data with additional business fields
  • GeoIP ISP: Internet service provider information
  • GeoIP Domain: Second-level domain data
  • GeoIP Connection Type: Connection type identification

Third-Party Databases:

  • DB-IP databases: Compatible with DB-IP's .mmdb format databases
  • IPinfo databases: Works with IPinfo's MaxMind DB format files
  • Custom databases: Any database following the MaxMind DB file format specification

The library is format-agnostic and will work with any valid .mmdb file regardless of the data provider.

Performance Tips

  1. Reuse Reader instances: Lookups, decoding, and iteration are safe to run concurrently. Close invalidates outstanding results, Reader-backed cursors, and their derived traversal handles; it must not run concurrently with their use and should run only after readers are done.
  2. Use specific structs: Only decode the fields you need rather than using any
  3. Generate a decoder: For high-throughput applications, use maxminddb-gen, or implement CursorUnmarshaler for custom decoding
  4. Consider caching: Use Result.Offset() as a cache key for database records

Getting Database Files

Free GeoLite2 Databases

Download from MaxMind's GeoLite page.

Documentation

  • Go Reference
  • MaxMind DB File Format Specification

Requirements

  • Go 1.26 or later
  • MaxMind DB file in .mmdb format

Contributing

Contributions welcome! Please fork the repository and open a pull request with your changes.

License

This is free software, licensed under the ISC License.

Issues· 0 开放

查看全部 Issues在 GitHub 打开

暂无开放 Issues,或尚未同步最近议题。

> 标签

Gogeoipgeoip2geolocationgo

暂无评论,来聊聊你的看法吧

> 工具信息

发布日期2026年8月1日
最后更新2026年9月17日
分类编程语言
定价开源

> 相关工具

T
TypeScript
JavaScript 的超集,为前端与全栈提供静态类型
P
Python
通用编程语言,广泛用于 Web、数据与 AI
G
Go
Google 推出的简洁高效系统语言