-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
cmd/integration: collection of commands to export db data into csv #11991
base: main
Are you sure you want to change the base?
Conversation
FYI: geth has
|
@AskAlexSharov thanks, I'll check it out. I'm exporting tables in CSV because it is easy to visualise in an IDE. I find it quite helpful for debugging purposes. E.g. I just run |
label := kv.ChainDB | ||
db, err := openDB(dbCfg(label, path.Join(datadirCli, label.String())), true, logger) | ||
if err != nil { | ||
logger.Error(err.Error()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i would advise move all logic to a func like doExportHeaderTD
- which will do usual return err
and here log error once.
copy(blockHash[8:], k) | ||
|
||
td := new(big.Int) | ||
if err := rlp.Decode(bytes.NewReader(v), td); err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use rlp.DecodeBytes
- it will do less allocs. (see: #12013 )
getter := seg.MakeGetter() | ||
for getter.HasNext() { | ||
var buf []byte | ||
buf, _ = getter.Next(buf) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
probably you want getter.Next(buf[:0])
seg := eventSegments[i] | ||
getter := seg.MakeGetter() | ||
for getter.HasNext() { | ||
var buf []byte |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
declare buf
outside of loop. then passing it to getter.Next
will give an effect (it will not alloc buf on every iteration)
var buf []byte | ||
buf, _ = getter.Next(buf) | ||
|
||
eventBytes := rlp.RawValue(libcommon.Copy(buf[length.Hash+length.BlockNum+8:])) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you dont use eventBytes
outside of loop iteration, then no reason to common.Copy
return | ||
} | ||
|
||
out, err := os.Create(outputCsvFile) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
probably you want defer f.Close()
snapDir := path.Join(datadirCli, "snapshots") | ||
logger.Info("snapshot dir info", "dir", snapDir) | ||
|
||
allSnapshots := freezeblocks.NewRoSnapshots(ethconfig.BlocksFreezing{}, snapDir, 0, logger) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pls use allSnapshots()
helper in integration. because it using global singletones - and in future they may conflict with your objects (theoreticaly)
} | ||
|
||
defer tx.Rollback() | ||
snapDir := path.Join(datadirCli, "snapshots") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pls use:
dirs := datadir.New(datadirCli)
dirs.Snap
from := make([]byte, 8) | ||
binary.BigEndian.PutUint64(from, max(fromNum, lastFrozenEventId+1)) | ||
var k, v []byte | ||
for k, v, err = c.Seek(from); iterateDb && err == nil && k != nil; k, v, err = c.Next() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
theoretically logic of db read and snapshots read - better add to BlockReader
object (like: .ForEachBorEvent()
) - but maybe you need very-custom logic - then fine.
Commands to export table+snapshot data for various tables:
The csv outputs can then be opened in an IDE. Makes life easier when debugging issues. Example, heimdall events table + snapshots:
![Screenshot 2024-09-14 at 16 04 31](https://private-user-images.githubusercontent.com/94537774/367524424-e5239df7-bce6-4fce-9d6b-3c27dfcac66a.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MzkyOTQ4MjksIm5iZiI6MTczOTI5NDUyOSwicGF0aCI6Ii85NDUzNzc3NC8zNjc1MjQ0MjQtZTUyMzlkZjctYmNlNi00ZmNlLTlkNmItM2MyN2RmY2FjNjZhLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAyMTElMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMjExVDE3MjIwOVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTRiNTc1YTAwYThjNGU3ZmU5NDY2NmU0MzliOWJlZjkwYWQ2NTMxNTcxMGJlY2JhYmU2ZTYwOGRkOGYxZTY4ODkmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.47GG-zLLz1HzI1kMivyW4MqbTN7acLbMnTlP0u06Vyw)