Bagaimana saya bisa melacak ketergantungan basis data?


37

Ketika aplikasi internal berkembang selama beberapa tahun, Anda kadang-kadang menemukan ada sejumlah tabel yang orang percaya tidak lagi relevan dan ingin disingkirkan. Apa metode praktis untuk mengidentifikasi dependensi database, baik di dalam lingkungan SQL, dan mungkin seterusnya ke hal-hal seperti SSIS?

Saya telah bekerja di tempat di mana opsi yang cukup brutal telah diambil seperti:

  • Lepas dulu, ajukan pertanyaan nanti (dapat mematikan pembangunan gudang data jika mencoba mengekstrak tabel yang tidak ada lagi)
  • Hapus izin terlebih dahulu, dan tunggu kesalahan dilaporkan (dapat menyebabkan bug diam, jika kegagalan tidak ditangani dengan benar)

Saya menghargai bahwa SQL Server dilengkapi dengan alat untuk melacak dependensi dalam contoh itu, tetapi ini tampaknya sulit jika Anda memiliki database pada contoh yang berbeda. Apakah ada opsi yang membuatnya lebih mudah untuk menanyakan dependensi, mungkin menjawab pertanyaan seperti "Di mana kolom ini digunakan?" dengan jawaban seperti "Over di server lain ini dalam prosedur tersimpan ini" atau "Over dalam paket SSIS ini"?

Jawaban:


14

Tidak ada cara mudah untuk melakukan ini. Pemicu tidak berfungsi, seolah-olah Anda memilih dari tabel tidak ada pemicu yang dipecat. Cara terbaik yang saya temukan untuk melakukan ini adalah membuat pengembang melacak apa yang mereka gunakan. Ketika sesuatu akan dibatalkan periksa dengan semua tim dev, dan setelah semua orang keluar, ganti nama objek. Maka tidak ada istirahat selama satu bulan atau, objek dapat dijatuhkan dengan aman.


7
  1. Cari kode untuk digunakan dengan sys.sql_modules.definition: apakah direferensikan? Kemudian...
  2. Periksa izin: kode klien apa yang bisa memanggilnya? Kemudian...
  3. Profiler

Demikian:

  • Untuk tabel tanpa referensi dan tanpa izin, itu tidak digunakan.
  • Tanpa referensi dan beberapa izin, jalankan profiler untuk melihat penggunaan
  • Tanpa izin dan referensi, tambahkan pencatatan penggunaan

Apa yang telah saya lakukan sebelumnya adalah membuat tampilan tabel menutupi tabel lalu membuat tampilan berkinerja buruk: (gabung dengan sendirinya, berbeda). Anda tidak benar-benar menghapusnya tetapi Anda menghasilkan waktu tunggu atau keluhan klien ...


6

Salah satu cara cepat yang saya gunakan di masa lalu (dan itu benar-benar tergantung pada ukuran tabel, jumlah kinerja indeks dll), adalah dengan menambahkan pemicu, yang mencatat timestamp ketika suatu tindakan dilakukan di atas meja. Seperti yang saya katakan ini dapat memiliki masalah kinerja, jadi perlu diperlakukan dengan hati-hati - juga perhatikan tabel logging Anda tidak menggunakan bidang identitas, karena ini dapat mengacaukan beberapa kode lama yang menggunakan @@ IDENTITY. Tentu saja itu mungkin hanya menunjukkan bahwa suatu fitur dalam suatu aplikasi belum pernah digunakan untuk suatu waktu.

Sangat sulit untuk melacak dependensi ketika semua kode yang mungkin mengenai database tidak ada dalam database yaitu klien acak yang meminta database.

EDIT: Untuk mengatasi titik bahwa tabel tidak dapat memiliki pemicu SELECT, berikut adalah opsi lain yang seharusnya berfungsi dengan asumsi tabel Anda memiliki indeks (hanya diuji pada 2008).

SELECT          
    last_user_seek,
    last_user_scan,
    last_user_lookup,
    last_user_update
FROM
    sys.dm_db_index_usage_stats AS usage_stats
INNER JOIN
sys.tables AS tables ON tables.object_id = usage_stats.object_id
WHERE
    database_id = DB_ID() AND
    tables.name = 'mytable' 

tetapi perhatikan bahwa tabel statistik penggunaan dihapus ketika server dihidupkan ulang, terlepas dll. Jadi, Anda perlu mengatur pekerjaan untuk mengumpulkan data. Sedikit peretasan saya tahu.


4

Salah satu cara yang saya gunakan di masa lalu adalah membuat daftar kandidat tabel untuk dihapus dan kemudian mengubah nama mereka dan mencari kegagalan.

Bagaimana saya menetapkan daftar itu:

  1. lihat tabel mana yang tidak digunakan dalam prosedur, pemicu, dan fungsi tersimpan saat ini

  2. tabel kosong (nol catatan);

  3. tabel tidak direferensikan (tabel yang tidak memiliki hubungan);

  4. lihat tabel mana yang tidak digunakan sejak DB Server dimulai (DMVs)

Setelah membangun daftar dalam file teks saya membuat skrip batch yang akan mem-parsing file .cs kami (kami hanya memiliki proyek .net) dari folder kontrol versi dipetakan lokal dan melihat apakah tabel tersebut digunakan dalam file .cs ( seharusnya tidak terjadi, tapi hei .. aku punya kejutan). Jika tidak, maka jelas, jika ya, maka kami membuat daftar dan memberikan kepada pengembang untuk memeriksa apakah modul itu masih digunakan.

Jadi, singkatnya, orang-orang sebelumnya benar, tidak ada peluru perak.


3

Kebijakan yang saya terapkan di perusahaan saya adalah meletakkan segala sesuatu yang menyentuh SQL Server di bawah kendali sumber, di lokasi pusat.

  • proyek asp.net
  • Proyek SSR
  • Proyek SSIS
  • Saya bahkan skrip semua objek database ke dalam semacam repositori.

Saya belum menyiapkannya, tetapi pada akhirnya saya ingin menerapkan semacam mekanisme pencarian indeks / pusat yang dapat saya gunakan untuk mencari tabel, sprocs, dll. Kami sebenarnya adalah SQL Server Shop baru - mengkonversi dari FoxPro . Objek SQL yang lama belum menjadi masalah, tapi saya berencana untuk masa depan.

Masalah yang saya lihat dengan pendekatan penggantian nama / penelusuran adalah bahwa beberapa hal hanya berjalan setiap tahun, dan bahkan tidak setiap tahun. Belum lagi berbagai hal ad-hoc yang diminta orang untuk Anda tulis, lalu minta lagi berbulan-bulan atau bertahun-tahun kemudian.


3

Ada berbagai alat dan teknik untuk digunakan dalam melacak dependensi, yang melibatkan:

Alat yang saya ketahui:

  • Penampil Ketergantungan SQL Server (tetapi dapat memiliki masalah jika sp menggunakan tabel dibuat sebelum tabel dibuat)
  • Redgate SQL Dependency Tracker (via jawaban @Eric Humphrey)
  • Resharper (alat .net yang dapat digunakan untuk melihat jalur panggilan, saya pikir itu dapat digunakan untuk melacak di mana kunci panggilan SQL digunakan)

Metode

  • Pencarian kode untuk menggunakan objek SQL (mereplikasi beberapa alat di atas sekalipun)
  • Lihatlah statistik penggunaan (yaitu: kapan objek SQL terakhir dipanggil), saya menggunakan SQL di bawah ini:

    SELECT 
        last_execution_time,   
        (SELECT TOP 1 
            SUBSTRING(s2.text,statement_start_offset / 2+1 , 
                ((CASE WHEN statement_end_offset = -1 THEN 
                    (LEN(CONVERT(nvarchar(max),s2.text)) * 2) 
                ELSE statement_end_offset END) - statement_start_offset) / 2+1)
        )  AS sql_statement,
        execution_count
    FROM sys.dm_exec_query_stats AS s1 
    CROSS APPLY sys.dm_exec_sql_text(sql_handle) AS s2  
    WHERE 
        s2.text like '%[OBJECT NAME]%' 
        and last_execution_time > [DATE YOU CARE ABOUT]
    ORDER BY last_execution_time desc

Catatan : Tabel statistik penggunaan dihapus ketika server dihidupkan ulang, terlepas dll. Jadi, Anda perlu mengatur pekerjaan untuk mengumpulkan data. Sedikit peretasan saya tahu. (dari @Miles D)

Teknik

  • Cari penggunaan terakhir (lihat statistik penggunaan di atas)
  • Cari di mana itu digunakan (lihat alat)
  • Tinjau penggunaan kode dengan pengembang (via @MrDenny)
  • Ganti nama objek (yaitu: posting / awalan dengan _toBeDropped) dan perhatikan kesalahannya
  • Ubah izin, dan perhatikan kesalahannya
  • Jatuhkan benda dan berdoa

2

Beberapa tahun yang lalu, saya mencoba membuat alat untuk memeriksa hal serupa. Jawaban TL; DR adalah bahwa saya merasa tidak mungkin melakukan dengan sumber daya yang tersedia saat itu.

Di mana kolom ini digunakan?

Pertanyaan ini menjadi lebih rumit ketika Anda menyadari bahwa sejumlah kueri, tampilan, dan prosedur tersimpan digunakan select *dari tabel tempat kolom tersebut berada. Kemudian Anda perlu melihat program yang menggunakan hasil tersebut - sehingga Anda memerlukan pemindai / pengindeks / pengurai mampu membaca kode sumber yang mungkin C #, Delphi, Java, VB, ASP (klasik) dan sebagainya hanya untuk mencoba memburu setiap referensi ke kolom itu. Maka Anda perlu menganalisis program-program itu untuk mencoba dan mengidentifikasi apakah kode itu bahkan dipanggil lagi.



2

Ini sebenarnya bukan jawaban untuk pertanyaan Anda, tetapi saya pikir itu perlu disebutkan: ini adalah salah satu alasan mengapa semua sistem di luar database Anda harus berkomunikasi melalui tampilan dan sprocs . Anda memiliki skrip build untuk ini dalam file .sql yang dapat dicari, sehingga Anda dapat dengan mudah melihat apakah tabel atau kolom tertentu digunakan secara eksternal.

Tentu saja SSIS biasanya akan terhubung langsung ke tabel, jadi ini mungkin tidak banyak membantu kebutuhan Anda saat ini. Tetapi ketika pengembang terhubung ke database Anda dan mengeluh karena harus menunggu Anda (atau siapa pun yang berfungsi sebagai DBA) untuk membuat tampilan dan sprocs yang mereka butuhkan, Anda dapat memberi tahu mereka: "Tabel atau kolom apa pun dapat dihapus atau diganti nama. Saya ' Saya hanya wajib memberi Anda informasi tentang perubahan pada tampilan dan sprocs. " Dan mereka hanya perlu melakukan pengujian regresi untuk perubahan spesifik ini.


0

TSQL berikut ini dapat digunakan sys.dm_sql_referencing_entities atau sys.sql_expression_dependencies

Atau alat-alat seperti SQL Negotiator Pro, Redgate dll dapat menghasilkan ini secara visual untuk Anda menggunakan GUI

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.