Linux inode 實現機制深入分析

Linux inode 實現機制深入分析

1 Inode 基本概念與作用

Inode(Index Node)是 Linux 和其他類 Unix 操作系統中文件系統的核心數據結構,用于存儲文件或目錄的元數據(metadata)。每個文件或目錄都有一個唯一的 inode,其中包含了除文件名以外的所有信息。inode 的本質是一個結構化的數據記錄,它連接了文件的邏輯組織與物理存儲。

1.1 inode 的重要性

在 Linux 文件系統中,inode 的作用主要體現在以下幾個方面:

  • 元數據存儲:inode 存儲了文件的關鍵屬性,包括權限、所有者、大小、時間戳等。
  • 數據定位:inode 包含了指向文件數據塊的指針,通過這種間接尋址方式,系統能夠高效地訪問文件內容。
  • 硬鏈接實現:多個文件名可以指向同一個 inode,這使得硬鏈接成為可能,inode 中的引用計數(i_nlink)跟蹤這些鏈接數量。

1.2 inode 與文件名、數據塊的關系

Linux 文件系統將存儲空間劃分為兩個獨立部分:

  • 元數據區域:存儲 inode 表,每個 inode 有唯一編號。
  • 數據區域:實際存儲文件內容的塊。

文件名與 inode 的映射關系存儲在目錄文件中。目錄本質上是包含文件名到 inode 編號映射的特殊文件。當用戶訪問一個文件時,系統首先在目錄中查找文件名對應的 inode 編號,然后通過該編號從 inode 表中獲取元數據,最后根據元數據中的數據塊指針訪問文件內容。

表:inode 中包含的主要元信息

字段描述示例值
i_inoinode 編號256789
i_mode文件類型和權限0o100644 (常規文件,rw-r–r--)
i_uid所有者用戶ID1000
i_gid所有者組ID1000
i_size文件大小(字節)102400
i_blocks使用的磁盤塊數200
i_atime最后訪問時間2023-10-30 08:00:00
i_mtime最后修改時間2023-10-29 19:30:00
i_ctimeinode 最后變更時間2023-10-29 19:30:00
i_nlink硬鏈接計數2

在這里插入圖片描述

不同的文件系統(如 ext4、XFS、Btrfs)在 inode 的具體實現上有所差異,但核心概念一致。例如,ext4 文件系統支持擴展屬性(xattr)和動態 inode 分配,而較老的 ext2 文件系統則有固定的 inode 數量限制。

2 Inode 的工作原理與實現機制

2.1 inode 的磁盤存儲結構

在磁盤上,文件系統被劃分為多個塊組(block groups)。每個塊組通常包含一個 inode 表(inode table)和一個用于記錄 inode 使用情況的位圖(inode bitmap)。inode 表是連續存儲的 inode 結構數組,每個 inode 的大小固定(如 ext4 中默認為 256 字節)。這種組織方式使得系統能夠快速定位和訪問特定編號的 inode。

超級塊(superblock)包含了整個文件系統的元信息,其中也記錄了 inode 的總數、已使用數以及每個 inode 的大小等信息。當文件系統被掛載時,超級塊的信息會被讀入內存,以便高效訪問。

2.2 inode 的內存管理機制

為了提高性能,Linux 內核會在內存中維護 inode 的緩存,即 inode cache。內存中的 inode 結構可能比磁盤上的更豐富,包含了一些運行時狀態。

2.2.1 slab 分配器

內核使用 slab 分配器來高效地分配和釋放 inode 對象。在系統初始化時,會創建一個名為 inode_cachep 的 slab 緩存,專門用于分配 inode 對象。這使得 inode 對象的分配和釋放非常快速,并有助于減少內存碎片。

// 內核中創建 inode slab 緩存的示例代碼(簡化)
static struct kmem_cache *inode_cachep;inode_cachep = kmem_cache_create("inode_cache",sizeof(struct inode),0,(SLAB_RECLAIM_ACCOUNT|SLAB_PANIC|SLAB_MEM_SPREAD),init_once);
2.2.2 inode 緩存與哈希表

內核維護了幾個鏈表來高效管理內存中的 inode:

  • inode_in_use:包含正在使用的 inode(引用計數 i_count > 0)。
  • inode_unused:包含未被使用的 inode(引用計數為 0,可被回收)。
  • 超級塊的 s_dirty:包含臟(已被修改但未寫回磁盤)的 inode。

為了快速通過 inode 編號和超級塊找到 inode,內核使用了一個哈希表 inode_hashtable。每個哈希桶包含一個鏈表,鏈接著具有相同哈希值的 inode 對象。

2.2.3 inode 的狀態與同步

內存中的 inode 有多種狀態,由 i_state 字段表示:

  • I_DIRTY:inode 是臟的,需要寫回磁盤。
  • I_LOCK:inode 正在被進行 I/O 操作。
  • I_FREEING:inode 正在被釋放。

臟 inode 會被定期(由 pdflush 線程)或強制(調用 sync() 系統調用)寫回磁盤。寫回操作由文件系統特定的 write_inode 方法處理。

2.3 inode 的主要操作

2.3.1 創建與初始化

當新文件或目錄被創建時,文件系統需要分配一個新的 inode。這個過程大致如下:

  1. 在 inode 位圖中查找一個空閑的 inode。
  2. 初始化該 inode 的元信息(如模式、所有者、時間戳等)。
  3. 將 inode 標記為已使用,并將其寫入 inode 表。

內核函數 get_empty_inode() 用于獲取一個空閑的 inode 對象:

struct inode *get_empty_inode(void) {struct inode *inode;// 從 slab 分配器分配一個 inode 對象inode = alloc_inode();if (inode) {spin_lock(&inode_lock);inodes_stat.nr_inodes++;// 將 inode 添加到 inode_in_use 鏈表list_add(&inode->i_list, &inode_in_use);// 初始化部分字段inode->i_sb = NULL;inode->i_dev = 0;inode->i_ino = ++last_ino;inode->i_flags = 0;atomic_set(&inode->i_count, 1);inode->i_state = 0;spin_unlock(&inode_lock);// 清理并初始化 inode 的其他字段clean_inode(inode);}return inode;
}
2.3.2 查找與獲取

當打開文件時,內核需要根據文件名找到對應的 inode。這個過程涉及目錄項緩存(dentry cache)和 inode 緩存 lookup。如果 inode 不在緩存中,文件系統必須從磁盤讀取它。函數 iget() 用于通過超級塊和 inode 編號獲取一個 inode 對象。如果 inode 不在緩存中,它會分配一個新的 inode 對象并調用文件系統特定的 read_inode 方法來填充它。

2.3.3 銷毀與釋放

當文件被刪除(硬鏈接計數降為 0)且沒有任何進程打開它時,其 inode 可以被釋放。這個過程包括:

  1. 將相關的數據塊標記為空閑。
  2. 在 inode 位圖中將該 inode 標記為空閑。
  3. 將 inode 對象返回給 slab 分配器。

函數 iput() 用于減少 inode 的引用計數,并在引用計數降為 0 時可能觸發釋放操作:

void iput(struct m_inode *inode) {if (!inode) return;wait_on_inode(inode);if (!inode->i_count)panic("iput: trying to free free inode");// ... 處理管道、塊設備、字符設備等特殊情況 ...if (inode->i_count > 1) {inode->i_count--;return;}if (!inode->i_nlinks) {truncate(inode); // 截斷文件,釋放數據塊free_inode(inode); // 釋放 inodereturn;}// ... 如果 inode 是臟的,寫回磁盤 ...inode->i_count--;
}

3 核心數據結構與代碼分析

3.1 主要數據結構

Linux 內核中 inode 的核心數據結構是 struct inode,它包含了文件的所有元數據信息以及用于操作和管理的字段。以下是其重要字段的詳細說明:

struct inode {// 基本字段umode_t            i_mode;       // 文件類型和權限unsigned short     i_opflags;    // 操作標志kuid_t             i_uid;        // 所有者用戶IDkgid_t             i_gid;        // 所有者組IDunsigned int       i_flags;      // 文件系統無關的標志// 鏈接和時間相關unsigned long      i_ino;        // Inode 編號unsigned int       i_nlink;      // 硬鏈接計數dev_t              i_rdev;       // 如果是設備文件,表示設備號loff_t             i_size;       // 文件大小(字節)struct timespec64 i_atime;       // 最后訪問時間struct timespec64 i_mtime;       // 最后修改時間(文件內容)struct timespec64 i_ctime;       // 最后狀態改變時間(inode 元數據)// 塊和存儲相關unsigned long      i_blocks;     // 文件占用的扇區數unsigned int       i_blkbits;    // 塊大小的位數(如 12 表示 4KB)blkcnt_t           i_blocks;     // 塊數量(已廢棄?)// 操作函數指針const struct inode_operations *i_op; // inode 操作const struct file_operations *i_fop; // 文件操作(當inode是文件時)struct super_block *i_sb;        // 所屬的超級塊struct address_space *i_mapping; // 頁緩存映射// 狀態和同步unsigned long      i_state;      // 狀態標志(I_DIRTY, I_LOCK等)struct mutex       i_mutex;      // 互斥鎖spinlock_t         i_lock;       // 自旋鎖// 引用計數atomic_t           i_count;      // 引用計數// 其他重要字段void              *i_private;    // 文件系統或設備的私有數據
};

除了 struct inode,還有一些相關的關鍵數據結構:

  • struct super_block:代表一個已掛載的文件系統實例,包含文件系統的全局信息,如塊大小、根 inode、inode 總數和空閑數,以及操作函數表 super_operations(包含了 alloc_inode, destroy_inode, write_inode 等方法)。
  • struct address_space:與 inode 關聯,用于管理文件的頁緩存(page cache)。它包含一個基數樹(radix tree)用于快速查找緩存頁,以及操作函數表 address_space_operations(如 readpage, writepage)。
  • struct file:代表一個打開的文件實例,包含當前讀寫位置(f_pos)、指向關聯 inode 的指針(f_inode)以及文件操作函數表(f_op)。

3.2 關鍵代碼分析

Linux 內核中 inode 相關的操作函數分布在各文件系統中,但有一些通用的函數和機制。

3.2.1 inode 初始化

inode_init_owner() 函數用于初始化新 inode 的所有權字段(uid 和 gid)。其邏輯是:如果沒有指定父目錄,或者父目錄沒有特定的 ACL(訪問控制列表)操作,則新 inode 的 uid 和 gid 通常繼承自父目錄。如果設置了 setuid 或 setgid 位,則進行相應處理。

void inode_init_owner(struct inode *inode, struct inode *dir, umode_t mode)
{kuid_t uid;kgid_t gid;if (dir && dir->i_op->get_acl)return;if (!dir || IS_ERR(dir))dir = current->fs->root_inode;/* 從父目錄獲取所有者 */uid = dir->i_uid;gid = dir->i_gid;/* 處理 setuid 和 setgid 位 */if ((mode & S_ISUID) != 0)uid = GLOBAL_ROOT_UID;if ((mode & S_ISGID) != 0)gid = GLOBAL_ROOT_GID;i_uid_write(inode, uid);i_gid_write(inode, gid);// ... 初始化時間和其他字段 ...
}
3.2.2 inode 緩存操作

iget_locked() 函數是 inode 緩存查找的核心。它嘗試通過超級塊和 inode 編號在哈希表中查找 inode。如果找到,則返回該 inode;如果沒有找到,則分配一個新的 inode 并將其插入哈希表,然后通知文件系統從磁盤填充該 inode。

4 簡單實例應用:獲取文件 inode 信息

為了加深對 inode 的理解,我們創建一個簡單的 C 程序,使用 stat 系統調用來獲取指定文件的 inode 信息并打印出來。這個實例展示了用戶空間程序如何訪問 inode 中的元數據。

4.1 源碼實現

#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>void print_file_info(const char *path) {struct stat statbuf;// 使用 stat 系統調用獲取文件信息,這些信息來自文件的 inodeif (stat(path, &statbuf) == -1) {fprintf(stderr, "Error getting info for '%s': %s\n", path, strerror(errno));return;}printf("Information for file: %s\n", path);printf("---------------------------\n");printf("Inode number: %lu\n", (unsigned long)statbuf.st_ino);printf("File size: %lld bytes\n", (long long)statbuf.st_size);printf("Number of blocks allocated: %lld\n", (long long)statbuf.st_blocks);printf("Block size: %ld bytes\n", (long)statbuf.st_blksize);// 打印文件類型和權限printf("File type: ");if (S_ISREG(statbuf.st_mode))printf("Regular file\n");else if (S_ISDIR(statbuf.st_mode))printf("Directory\n");else if (S_ISCHR(statbuf.st_mode))printf("Character device\n");else if (S_ISBLK(statbuf.st_mode))printf("Block device\n");else if (S_ISFIFO(statbuf.st_mode))printf("FIFO/pipe\n");else if (S_ISSOCK(statbuf.st_mode))printf("Socket\n");else if (S_ISLNK(statbuf.st_mode))printf("Symbolic link\n");elseprintf("Unknown?\n");printf("Permissions: %o\n", statbuf.st_mode & 0777);printf("Link count: %lu\n", (unsigned long)statbuf.st_nlink);// 打印所有權信息printf("Ownership: UID=%ld, GID=%ld\n", (long)statbuf.st_uid, (long)statbuf.st_gid);// 轉換并打印時間戳printf("Last access: %s", ctime(&statbuf.st_atime));printf("Last modification: %s", ctime(&statbuf.st_mtime));printf("Last status change: %s", ctime(&statbuf.st_ctime));printf("\n");
}int main(int argc, char *argv[]) {if (argc < 2) {fprintf(stderr, "Usage: %s <file1> [file2] ...\n", argv[0]);exit(EXIT_FAILURE);}for (int i = 1; i < argc; i++) {print_file_info(argv[i]);}return 0;
}

4.2 編譯與運行

  1. 將上述代碼保存為 inode_info.c
  2. 使用 gcc 編譯:
    gcc -o inode_info inode_info.c
    
  3. 運行程序并指定文件路徑:
    ./inode_info /etc/passwd /var/log/syslog
    

4.3 輸出示例

程序運行后,會輸出指定文件的 inode 信息,如下所示:

Information for file: /etc/passwd
---------------------------
Inode number: 787061
File size: 2416 bytes
Number of blocks allocated: 8
Block size: 4096 bytes
File type: Regular file
Permissions: 644
Link count: 1
Ownership: UID=0, GID=0
Last access: Wed Oct 25 10:30:45 2023
Last modification: Wed Oct 25 10:30:45 2023
Last status change: Wed Oct 25 10:30:45 2023

這個程序直觀地展示了 inode 中存儲的關鍵信息,包括 inode 編號、文件大小、權限、鏈接數等,這些都是文件系統管理文件的核心元數據。

5 常用工具命令和 debug 手段

管理和調試 Linux 文件系統及 inode 的工具有很多,以下是一些常用命令和方法的總結,并結合實例說明其用法。

5.1 命令行工具

表:常用的 inode 相關命令

命令主要功能示例用法說明
stat顯示文件 inode 的元數據stat file.txt查看文件的詳細信息(inode 編號、權限、大小、時間戳等)
ls列出目錄內容ls -li-i 選項顯示每個文件的 inode 編號
df報告文件系統磁盤空間使用情況df -i-i 選項顯示 inode 使用情況而非塊使用情況
debugfs文件系統調試器debugfs /dev/sda1交互式檢查和管理文件系統,可查看和修改 inode
dumpe2fs顯示 ext2/3/4 文件系統信息dumpe2fs /dev/sda1 \| grep -i inode顯示超級塊中關于 inode 的信息(總數、空閑數、大小等)
5.1.1 使用 debugfs 查看 inode 詳細信息

debugfs 是一個強大的交互式文件系統調試工具,可以用來檢查和處理文件系統的狀態,包括直接查看和操作 inode。

示例:查看文件的創建時間(crtime)

# 首先查找文件所在的設備
df /path/to/file
# 輸出示例:/dev/sda1       100663296 36740736  63768576  37% /# 使用 ls -i 獲取文件的 inode 號
ls -i /path/to/file
# 輸出示例:787061 file.txt# 使用 debugfs 的 stat 命令查看 inode 詳細信息
sudo debugfs -R 'stat <787061>' /dev/sda1

在輸出信息中,可以找到 crtime 字段,即文件的創建時間,這是 stat 命令通常不顯示的信息。

在這里插入圖片描述

5.1.2 使用 dumpe2fs 查看文件系統級 inode 信息

dumpe2fs 可以顯示 ext 系列文件系統的超級塊和塊組詳細信息,其中包含整個文件系統中 inode 的總體情況。

sudo dumpe2fs /dev/sda1 | grep -i "inode count"
# 輸出:Inode count:              6553600
#       Free inodes:              5121234sudo dumpe2fs /dev/sda1 | head -n 50
# 顯示文件系統信息的前50行,包含每個塊組的 inode 信息

5.2 內核調試手段

對于內核開發者或需要深入排查文件系統問題的情況,有以下更高級的調試手段:

  • GDB 與 KGDB:可以使用 GDB(配合 KGDB 進行內核調試)在內核代碼中設置斷點,例如在 iput(), iget() 等函數處,單步跟蹤 inode 的分配、引用和釋放過程。
  • 內核 Tracepoints 和 Ftrace:利用內核內置的跟蹤工具(如 trace-cmd)來監控與 inode 相關的內核函數調用事件,這對于分析性能問題或競爭條件非常有用。
  • 打印 inode 狀態信息:在內核代碼中添加 printk 語句(需重新編譯內核),打印特定 inode 的狀態、引用計數變化等信息。
    // 示例:在 iput 函數中添加打印
    printk(KERN_DEBUG "iput: ino=%lu, count=%d, nlink=%u\n",inode->i_ino, atomic_read(&inode->i_count), inode->i_nlink);
    
  • 查看 /proc/slabinfoslabinfo 提供了系統中 slab 緩存的使用情況,可以查看 inode_cache 的活動情況,幫助判斷 inode 緩存是否存在泄漏或過度使用。
    cat /proc/slabinfo | grep inode_cache
    

5.3 處理常見問題

  • "No space left on device" (但 df 顯示有空間):這通常是 inode 耗盡導致的。使用 df -i 確認。解決方法:清理無用的小文件或臨時文件;或者重新格式化文件系統并分配更多的 inode(如使用 mkfs.ext4 -N number_of_inodes)。
  • 文件刪除后空間未釋放:如果還有進程打開著某個文件,即使你刪除了它(即從目錄中移除了硬鏈接),其 inode 和數據塊也不會立即釋放,直到所有打開的文件描述符都關閉。使用 lsof | grep deleted 查找此類文件。
  • 使用 debugfs 恢復誤刪除的文件:如果文件剛被刪除,且其 inode 和數據塊尚未被重用,有可能通過 debugfs 恢復。
    1. 使用 ls -ld /path/to/deleted/file 的 inode 號(如果還記得路徑)。
    2. 或用 debugfs -R 'ls -d /path/to/parent_dir' /dev/device 查看已刪除的條目(標記為 <deleted>)。
    3. debugfs -R 'dump <inode> /tmp/recovered_file' /dev/device 嘗試導出數據。

6 總結與展望

通過本分析,我們深入探討了 Linux inode 的工作原理、實現機制和代碼框架。inode 作為 Linux 文件系統的基石,其高效管理對系統性能和可靠性至關重要。

  • inode 是文件的元數據容器:它存儲了文件的所有屬性(權限、所有者、大小、時間戳等),并通過數據塊指針指向文件的實際內容。
  • 磁盤與內存雙重表示:磁盤上的 inode 結構持久化存儲元數據;內存中的 inode 對象(struct inode)則包含了運行時狀態,并通過 slab 分配器、緩存鏈表和哈希表進行高效管理。
  • 操作基于引用計數:inode 的創建、查找、使用和銷毀都緊密圍繞著引用計數(i_count)和硬鏈接計數(i_nlink)展開,iget()iput() 是維護這些計數的關鍵函數。
  • 工具鏈豐富強大:從用戶空間的 stat, ls, df, debugfs 到內核空間的調試手段,Linux 提供了多種工具來監控、分析和調試 inode 及文件系統行為。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/94660.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/94660.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/94660.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Flask 之請求鉤子詳解:掌控請求生命周期

在構建現代 Web 應用時&#xff0c;我們常常需要在請求的不同階段自動執行一些通用邏輯&#xff0c;例如&#xff1a;記錄日志、驗證權限、連接數據庫、壓縮響應、添加安全頭等。如果在每個視圖函數中重復這些代碼&#xff0c;不僅冗余&#xff0c;而且難以維護。Flask 請求鉤子…

設計模式七大原則附C++正反例源碼

設計模式的七大原則是軟件設計的基石,它們指導開發者構建高內聚、低耦合、易維護、可擴展的系統。以下以C++為例,詳細介紹這七大原則: 一、單一職責原則(Single Responsibility Principle, SRP) 定義:一個類應該只有一個引起它變化的原因(即一個類只負責一項職責)。 …

云計算之中間件與數據庫

一、云數據庫的特性云數據庫是指被優化或部署到一個虛擬計算環境中的數據庫&#xff0c;可以實現按需付費、按需擴展、高可用性以及存儲整合等優勢。根據數據庫類型一般分為關系型數據庫和非關系型數據庫&#xff08;NoSQL數據庫&#xff09; 。云數據庫的特性序號云數據庫的特…

codeforces(1045)(div2) E. Power Boxes

E.電源箱 每次測試時限&#xff1a; 2 秒 每次測試的內存限制&#xff1a;256 兆字節 輸入&#xff1a;標準輸入 輸出&#xff1a;標準輸出 這是一個互動問題。 給你 nnn 個方格&#xff0c;索引從 111 到 nnn 。這些方格看起來完全相同&#xff0c;但是每個方格都有一個隱藏的…

4G模塊 EC200通過MQTT協議連接到阿里云

命令說明 基礎AT指令ATI顯示MT的ID信息ATCIMI查詢IMSIATQCCID查詢ICCIDATCSQ查詢信號強度ATCGATT?查詢當前PS域狀態MQTT配置指令ATQMTCFG配置MQTT可選參數ATQMTCFG配置MQTT可選參數.ATQMTOPEN打開MQTT客戶端網絡ATQMTCLOSE關閉MQTT客戶端網絡ATQMTCONN連接客戶端到MQTT服務器…

如何選擇合適的安全監測預警系統

在當今高度復雜和互聯的數字化時代&#xff0c;安全威脅無處不在且持續演變。一套高效、可靠的安全監測預警系統已成為組織保障其物理資產、數字信息和關鍵業務連續性的核心基礎設施。然而&#xff0c;面對市場上琳瑯滿目的產品和解決方案&#xff0c;如何做出符合自身需求的選…

ELK-使用logstash-output-zabbix插件實現日志通過zabbix告警

ELK-使用logstash-output-zabbix插件實現日志通過zabbix告警logstash-output-zabbix插件安裝編輯logstash配置文件在zabbix上創建模板實現的效果:elk收集上來的日志中含有報錯時(例如error等)&#xff0c;logstash過濾出來將這部分日志打到zabbix&#xff0c;再通過zabbix結合釘…

【C++游記】物種多樣——謂之多態

楓の個人主頁 你不能改變過去&#xff0c;但你可以改變未來 算法/C/數據結構/C Hello&#xff0c;這里是小楓。C語言與數據結構和算法初階兩個板塊都更新完畢&#xff0c;我們繼續來學習C的內容呀。C是接近底層有比較經典的語言&#xff0c;因此學習起來注定枯燥無味&#xf…

Visual Scope (Serial_Digital_Scope V2) “串口 + 虛擬示波器” 工具使用記錄

VisualScope 就是一個 “串口 + 虛擬示波器” 的工具,適合在沒有昂貴示波器/邏輯分析儀時做嵌入式調試。它的核心步驟就是 MCU 定時發數據 → PC 串口接收 → 軟件畫波形。 首先準備串口通信工具后,插入電腦,安裝完USB轉串口驅動后,在“我的電腦”-“設備及管理器”-“端口…

c++ 觀察者模式 訂閱發布架構

#include <iostream> #include <vector> #include <algorithm> #include <memory> #include <mutex>// 觀察者接口 class IObserver { public:virtual ~IObserver() default;virtual void update(const std::string& message) 0; };// 主題…

oracle 表空間擴容(增加新的數據文件)

SELECT tablespace_name,file_name,ROUND(bytes / 1024 / 1024, 2) AS size_mb,ROUND(maxbytes / 1024 / 1024, 2) AS max_size_mb,status,autoextensible FROM dba_data_files ORDER BY tablespace_name;--給表空間增加一個新數據庫文件ALTER TABLESPACE EAS_D_EAS_STANDARDAD…

DAY 58 經典時序預測模型2

知識點回顧&#xff1a; 時序建模的流程時序任務經典單變量數據集ARIMA&#xff08;p&#xff0c;d&#xff0c;q&#xff09;模型實戰SARIMA摘要圖的理解處理不平穩的2種差分 n階差分---處理趨勢季節性差分---處理季節性 昨天我們掌握了AR, MA, 和 ARMA 模型&#xff0c;它們…

【人工智能】AI代理重塑游戲世界:動態NPC帶來的革命性沉浸式體驗

還在為高昂的AI開發成本發愁?這本書教你如何在個人電腦上引爆DeepSeek的澎湃算力! 在當今游戲行業迅猛發展的時代,AI代理技術正悄然引發一場革命,尤其是動態非玩家角色(NPC)的應用,將傳統靜態游戲體驗提升至全新的沉浸式境界。本文深入探討AI代理在游戲中的核心作用,從…

服務器關機故障排查:大白話版筆記

注意:本文解釋文字僅供學習交流使用,不構成專業的技術指導或建議;只是理論實例解釋不代表實際運維場景操作,注意鑒別! 運維日常最頭疼的就是服務器 “突然躺平” —— 要么沒操作就自己關機,要么想關還關不掉。 緊急檢查清單 (Cheat Sheet) 服務器突然宕機,重啟后第一…

如何通過docker進行本地部署?

如何通過docker進行本地部署&#xff1f; 在做項目的過程中&#xff0c;想要上線項目的話肯定是不能在我們電腦上進行開發的&#xff0c;要部署到服務器上面&#xff0c;今天就總結一下操作步驟。 1、創建springboot項目 隨便創建一個springboot工程&#xff0c;確保control…

解鎖AI“黑匣”:監督、無監督與強化學習探秘

在當今數字化浪潮洶涌澎湃的時代&#xff0c;AI 決策已然成為推動各領域變革與發展的核心驅動力&#xff0c;從智能語音助手到自動駕駛汽車&#xff0c;從醫療診斷輔助到金融風險預測&#xff0c;AI 決策的身影無處不在&#xff0c;深刻地改變著人們的生活與工作方式。?AI 決策…

F008 vue+flask 音樂推薦評論和可視化系統+帶爬蟲前后端分離系統

文章結尾部分有CSDN官方提供的學長 聯系方式名片 文章結尾部分有CSDN官方提供的學長 聯系方式名片 關注B站&#xff0c;有好處&#xff01; F008 &#x1f3b6;vueflask 音樂推薦和可視化系統帶爬蟲前后端分離系統 編號&#xff1a;F008 B站視頻介紹&#xff1a; vueflask-云音…

海盜王64位dx9客戶端修改篇之二

目前全網&#xff0c;估計也就只有這個是海盜王客戶端3.0的原始版直接升級成64位dx9的了。客戶端非常簡潔&#xff0c;連64位lua都集成進去&#xff0c;除了新更換的64位SDL音樂播放庫dll沒辦法集成外&#xff0c;沒有任何多余的其他文件了。 之前有其他大佬將1.38的改成了dx9的…

點評項目(Redis中間件)第二部分Redis基礎

Redis的java客戶端spring整合了前三種我們只需要學習spring整合的就行了。不過還是有企業使用老一套的原生的jedis。jedis操作引入依賴<dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>3.7.0</ve…